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:
Kirk McKusick 2020-04-03 20:43:25 +00:00
parent aedb9cc662
commit 2baca88584
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=359613

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