summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2008-01-03 12:28:57 +0000
committerkib <kib@FreeBSD.org>2008-01-03 12:28:57 +0000
commit149cd5b092a10623753758846599e566ae3a2264 (patch)
tree841aa963960012b020a2fe20cefe062876f0748d /sys/ufs
parent545d26e30bb60df264b73543bf214c7e006f18fb (diff)
downloadFreeBSD-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.c28
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);
}
OpenPOWER on IntegriCloud