Date: Thu, 24 Feb 2000 01:48:14 +0000 From: Ian Dowse <iedowse@maths.tcd.ie> To: Matthew Dillon <dillon@apollo.backplane.com> Cc: freebsd-current@freebsd.org Subject: Re: ffs_blkfree: freeing free block (was Re: Panic (pmap)) Message-ID: <200002240148.aa34053@salmon.maths.tcd.ie> In-Reply-To: Your message of "Wed, 23 Feb 2000 22:35:29 GMT." <200002232235.aa22335@salmon.maths.tcd.ie>
next in thread | previous in thread | raw e-mail | index | archive | help
In message <200002232235.aa22335@salmon.maths.tcd.ie>, Ian Dowse writes: > >The fix should be relatively straightforward - either the code should >avoid linking new indirection blocks until all allocations succeed, >or it should back out the changes on failure. Here's one patch that seems to fix the problem. It may not be the best approach though? Ian --- ffs_balloc.c.orig Thu Feb 24 00:44:32 2000 +++ ffs_balloc.c Thu Feb 24 01:45:46 2000 @@ -71,7 +71,7 @@ int flags; struct fs *fs; ufs_daddr_t nb; - struct buf *bp, *nbp; + struct buf *bp, *nbp, *allocbp; struct vnode *vp; struct indir indirs[NIADDR + 2]; ufs_daddr_t newb, *bap, pref; @@ -197,6 +197,7 @@ --num; nb = ip->i_ib[indirs[0].in_off]; allocib = NULL; + allocbp = NULL; allocblk = allociblk; if (nb == 0) { pref = ffs_blkpref(ip, lbn, 0, (ufs_daddr_t *)0); @@ -272,6 +273,17 @@ } } bap[indirs[i - 1].in_off] = nb; + if (allocib == NULL) { + /* + * Writing bp would link in the newly allocated + * blocks; hold off in case of allocation failure + * later. + */ + allocib = &bap[indirs[i - 1].in_off]; + allocbp = bp; + continue; + } + /* * If required, write synchronously, otherwise use * delayed write. @@ -316,8 +328,7 @@ bp->b_flags |= B_CLUSTEROK; bdwrite(bp); } - *ap->a_bpp = nbp; - return (0); + goto success; } brelse(bp); if (flags & B_CLRBUF) { @@ -330,6 +341,22 @@ nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0); nbp->b_blkno = fsbtodb(fs, nb); } +success: + if (allocbp != NULL) { + /* + * It is safe to write allocbp now. + * + * If required, write synchronously, otherwise use + * delayed write. + */ + if (flags & B_SYNC) { + bwrite(allocbp); + } else { + if (allocbp->b_bufsize == fs->fs_bsize) + allocbp->b_flags |= B_CLUSTEROK; + bdwrite(allocbp); + } + } *ap->a_bpp = nbp; return (0); fail: @@ -349,8 +376,11 @@ ffs_blkfree(ip, *blkp, fs->fs_bsize); deallocated += fs->fs_bsize; } - if (allocib != NULL) + if (allocib != NULL) { *allocib = 0; + if (allocbp != NULL) + brelse(allocbp); + } if (deallocated) { #ifdef QUOTA /* To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi? <200002240148.aa34053>