diff options
author | kib <kib@FreeBSD.org> | 2008-01-03 12:28:57 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2008-01-03 12:28:57 +0000 |
commit | 149cd5b092a10623753758846599e566ae3a2264 (patch) | |
tree | 841aa963960012b020a2fe20cefe062876f0748d /sys/ufs | |
parent | 545d26e30bb60df264b73543bf214c7e006f18fb (diff) | |
download | FreeBSD-src-149cd5b092a10623753758846599e566ae3a2264.zip FreeBSD-src-149cd5b092a10623753758846599e566ae3a2264.tar.gz |
ffs_balloc_ufsX() routines, in the case of recovering from the failed
allocation, free the indirect blocks before clearing the disk pointers,
that could lead to the softupdate inconsistencies in the case of the
machine or disk crash at the wrong time.
Rearrange the recover code to do the ffs_blkfree() after the second
ffs_syncvnode(), that clears the pointers chain.
Proposed and reviewed by: tegge
Tested by: Peter Holm
MFC after: 3 weeks
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ffs/ffs_balloc.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c index d74b00c..4d4fa89 100644 --- a/sys/ufs/ffs/ffs_balloc.c +++ b/sys/ufs/ffs/ffs_balloc.c @@ -420,12 +420,6 @@ fail: bp->b_flags &= ~B_ASYNC; brelse(bp); } - - /* - * After the buffer is invalidated, free the block. - */ - ffs_blkfree(ump, fs, ip->i_devvp, *blkp, fs->fs_bsize, - ip->i_number); deallocated += fs->fs_bsize; } if (allocib != NULL) { @@ -461,6 +455,14 @@ fail: ip->i_flag |= IN_CHANGE | IN_UPDATE; } (void) ffs_syncvnode(vp, MNT_WAIT); + /* + * After the buffers are invalidated and on-disk pointers are + * cleared, free the blocks. + */ + for (blkp = allociblk; blkp < allocblk; blkp++) { + ffs_blkfree(ump, fs, ip->i_devvp, *blkp, fs->fs_bsize, + ip->i_number); + } return (error); } @@ -918,12 +920,6 @@ fail: bp->b_flags &= ~B_ASYNC; brelse(bp); } - - /* - * After the buffer is invalidated, free the block. - */ - ffs_blkfree(ump, fs, ip->i_devvp, *blkp, fs->fs_bsize, - ip->i_number); deallocated += fs->fs_bsize; } if (allocib != NULL) { @@ -959,5 +955,13 @@ fail: ip->i_flag |= IN_CHANGE | IN_UPDATE; } (void) ffs_syncvnode(vp, MNT_WAIT); + /* + * After the buffers are invalidated and on-disk pointers are + * cleared, free the blocks. + */ + for (blkp = allociblk; blkp < allocblk; blkp++) { + ffs_blkfree(ump, fs, ip->i_devvp, *blkp, fs->fs_bsize, + ip->i_number); + } return (error); } |