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>
