ext2fs crash in -current (r218056)

John Baldwin jhb at freebsd.org
Wed Feb 2 22:04:08 UTC 2011


On Wednesday, February 02, 2011 04:13:48 pm Doug Barton wrote:
> I haven't had a chance to test this patch yet, but John's did not work
> (sorry):
> 
> http://dougbarton.us/ext2fs-crash-dump-2.jpg
> 
> No actual dump this time either.
> 
> I'm happy to test the patch below on Thursday if there is consensus that
> it will work.

Err, this is a different panic than what you reported earlier.  Your disk died 
and spewed a bunch of EIO errors.  I can look at the locking assertion failure 
tomorrow, but this is a differnt issue.  Even UFS needed a good bit of work to 
handle disks dying gracefully.

> Doug
> 
> On 02/01/2011 17:42, Aditya Sarawgi wrote:
> > 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
> > _______________________________________________
> > freebsd-fs at freebsd.org mailing list
> > http://lists.freebsd.org/mailman/listinfo/freebsd-fs
> > To unsubscribe, send any mail to "freebsd-fs-unsubscribe at freebsd.org"

-- 
John Baldwin


More information about the freebsd-fs mailing list