ext2fs crash in -current (r218056)

Aditya Sarawgi sarawgi.aditya at gmail.com
Wed Feb 2 02:11:42 UTC 2011


Hi John,

I can see what you are saying. Can't we check 
the number of free blocks in the given cg without
locking the fs. 
This way 

  		EXT2_LOCK(ump);
  		return (0);
  	}
 +	if (fs->e2fs_gd[cg].ext2bgd_nbfree == 0) {
 +		/*
 +		 * Another thread allocated the last block in this
 +		 * group while we were waiting for the buffer.
 +		 */
 +		brelse(bp);
 +		EXT2_LOCK(ump);
 +		return (0);
 +	}
  	bbp = (char *)bp->b_data;
  
  	if (dtog(fs, bpref) != cg)


UFS is doing something similar 

static ufs2_daddr_t
ffs_alloccg(ip, cg, bpref, size, rsize)
  struct inode *ip;
  u_int cg;
  ufs2_daddr_t bpref;
  int size;
  int rsize;
{
  struct fs *fs;
  struct cg *cgp;
  struct buf *bp;
  struct ufsmount *ump;
  ufs1_daddr_t bno;
  ufs2_daddr_t blkno;
  int i, allocsiz, error, frags;
  u_int8_t *blksfree;

  ump = ip->i_ump;
  fs = ip->i_fs;
  if (fs->fs_cs(fs, cg).cs_nbfree == 0 && size == fs->fs_bsize)
    return (0);
  UFS_UNLOCK(ump);
  error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
    (int)fs->fs_cgsize, NOCRED, &bp);
  if (error)
    goto fail;
  cgp = (struct cg *)bp->b_data;
  if (!cg_chkmagic(cgp) ||
      (cgp->cg_cs.cs_nbfree == 0 && size == fs->fs_bsize))
    goto fail;
> Please try this:
> 
> Index: ext2_alloc.c
> ===================================================================
> --- ext2_alloc.c	(revision 218175)
> +++ ext2_alloc.c	(working copy)
> @@ -650,6 +650,18 @@
>  		EXT2_LOCK(ump);
>  		return (0);
>  	}
> +	EXT2_LOCK(ump);
> +	if (fs->e2fs_gd[cg].ext2bgd_nbfree == 0) {
> +		/*
> +		 * Another thread allocated the last block in this
> +		 * group while we were waiting for the buffer.
> +		 */
> +		EXT2_UNLOCK(ump);
> +		brelse(bp);
> +		EXT2_LOCK(ump);
> +		return (0);
> +	}
> +	EXT2_UNLOCK(ump);
>  	bbp = (char *)bp->b_data;
>  
>  	if (dtog(fs, bpref) != cg)
> @@ -776,6 +788,18 @@
>  		EXT2_LOCK(ump);
>  		return (0);
>  	}
> +	EXT2_LOCK(ump);
> +	if (fs->e2fs_gd[cg].ext2bgd_nifree == 0) {
> +		/*
> +		 * Another thread allocated the last i-node in this
> +		 * group while we were waiting for the buffer.
> +		 */
> +		EXT2_UNLOCK(ump);
> +		brelse(bp);
> +		EXT2_LOCK(ump);
> +		return (0);
> +	}
> +	EXT2_UNLOCK(ump);	
>  	ibp = (char *)bp->b_data;
>  	if (ipref) {
>  		ipref %= fs->e2fs->e2fs_ipg;

--
Aditya Sarawgi


More information about the freebsd-fs mailing list