When a file is partially truncated, we first check to see if the

new file end will land in the middle of a file hole. Since the last
block of a file must always be allocated, the hole is filled by
allocating a block at that location. If the hole being filled is
a direct block, then the truncation may eventually reduce the
full sized block down to a fragment. When running with soft
updates, it is necessary to FSYNC the file after allocating the
block and before creating the fragment to avoid triggering a
soft updates inconsistency when the block unexpectedly shrinks.

Found by:	Matthew Dillon <dillon@apollo.backplane.com>
MFC after:	1 week
This commit is contained in:
Kirk McKusick 2001-12-13 05:07:48 +00:00
parent bcb733d069
commit 9db12e5108

View File

@ -250,6 +250,18 @@ ffs_truncate(vp, length, flags, cred, td)
if (error) {
return (error);
}
/*
* When we are doing soft updates and the UFS_BALLOC
* above fills in a direct block hole with a full sized
* block that will be truncated down to a fragment below,
* we must flush out the block dependency with an FSYNC
* so that we do not get a soft updates inconsistency
* when we create the fragment below.
*/
if (DOINGSOFTDEP(ovp) && lbn < NDADDR &&
fragroundup(fs, blkoff(fs, length)) < fs->fs_bsize &&
(error = VOP_FSYNC(ovp, cred, MNT_WAIT, td)) != 0)
return (error);
oip->i_size = length;
size = blksize(fs, oip, lbn);
if (ovp->v_type != VDIR)