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
This commit is contained in:
kib 2008-01-03 12:28:57 +00:00
parent 545d26e30b
commit 149cd5b092

View File

@ -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);
}