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>