Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 Feb 2011 07:12:55 +0530
From:      Aditya Sarawgi <sarawgi.aditya@gmail.com>
To:        John Baldwin <jhb@freebsd.org>
Cc:        freebsd-fs@freebsd.org
Subject:   Re: ext2fs crash in -current (r218056)
Message-ID:  <20110202014252.GA1574@earth>
In-Reply-To: <201102011352.57998.jhb@freebsd.org>
References:  <4D47B954.3010600@FreeBSD.org> <201102011352.57998.jhb@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20110202014252.GA1574>