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