When shrinking the size of a directory it is sometimes necessary to

sync it to disk before shrinking it. Complete the sync before getting
the buffer for the block to be updated to do the shrink to avoid
panicing with a recursive lock on one of the directory's buffers.

Reviewed by:  Chuck Silvers (chs)
MFC after:    3 days
Sponsored by: Netflix
This commit is contained in:
mckusick 2020-04-03 20:43:25 +00:00
parent a4d7675c81
commit fdcad7c272

View File

@ -426,11 +426,6 @@ ffs_truncate(vp, length, flags, cred)
ip->i_size = length;
DIP_SET(ip, i_size, length);
} else {
lbn = lblkno(fs, length);
flags |= BA_CLRBUF;
error = UFS_BALLOC(vp, length - 1, 1, cred, flags, &bp);
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
@ -439,10 +434,15 @@ ffs_truncate(vp, length, flags, cred)
* so that we do not get a soft updates inconsistency
* when we create the fragment below.
*/
lbn = lblkno(fs, length);
if (DOINGSOFTDEP(vp) && lbn < UFS_NDADDR &&
fragroundup(fs, blkoff(fs, length)) < fs->fs_bsize &&
(error = ffs_syncvnode(vp, MNT_WAIT, 0)) != 0)
return (error);
flags |= BA_CLRBUF;
error = UFS_BALLOC(vp, length - 1, 1, cred, flags, &bp);
if (error)
return (error);
ip->i_size = length;
DIP_SET(ip, i_size, length);
size = blksize(fs, ip, lbn);