quick fix for slow directory shrinking in ffs

Bruce Evans brde at optusnet.com.au
Mon May 16 21:54:37 UTC 2016


ffs does very slow shrinking of directories after removing some files
leaves unused blocks at the end, by always doing synchronous truncation.

This often happens in my normal usage: medium size builds expand /tmp
from 512 to 1024 to hold a few more hundred bytes of file names;
expansion is async and fast, but shrinking is sync and slow, and
with a certain size of build the boundary is crossed back and forth
very often.

My /tmp directory is always on an async-mounted file system, so this
quick fix of always doing an async truncation for async mounts works
for me.  Using IO_SYNC when not asked to is a bug for async mounts
in all cases anyway.

The file system has block size 8192 and frag size 1024, so it is also
wrong to shrink to size DIRBLKSIZE = 512.  The shrinkage seems to be
considered at every DIRBLKSIZE boundary, so not only small directories
are affected.

The patch fixes an unrelated typo in a message.

X Index: ufs_lookup.c
X ===================================================================
X --- ufs_lookup.c	(revision 299263)
X +++ ufs_lookup.c	(working copy)
X @@ -1131,9 +1131,9 @@
X  		if (tvp != NULL)
X  			VOP_UNLOCK(tvp, 0);
X  		error = UFS_TRUNCATE(dvp, (off_t)dp->i_endoff,
X -		    IO_NORMAL | IO_SYNC, cr);
X +		    IO_NORMAL | (DOINGASYNC(dvp) ? 0 : IO_SYNC), cr);
X  		if (error != 0)
X -			vprint("ufs_direnter: failted to truncate", dvp);
X +			vprint("ufs_direnter: failed to truncate", dvp);
X  #ifdef UFS_DIRHASH
X  		if (error == 0 && dp->i_dirhash != NULL)
X  			ufsdirhash_dirtrunc(dp, dp->i_endoff);

Bruce


More information about the freebsd-fs mailing list