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:
parent
bcb733d069
commit
9db12e5108
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user