quick fix for slow directory shrinking in ffs

Konstantin Belousov kostikbel at gmail.com
Tue May 17 08:20:57 UTC 2016


On Tue, May 17, 2016 at 07:54:27AM +1000, Bruce Evans wrote:
> 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);
> 

The IO_SYNC flag, for non-journaled SU and any kind of non-SU mounts,
only affects the new blocks allocation mode, and write-out mode for
the last fragment. The truncation itself (for -J) is performed in the
context of the truncating thread. The cg blocks, after the bits are
set to free, are marked for delayed write (with the background write
hack). The inode block is written according to the mount mode, ignoring
IO_SYNC.

That is, for always fully populated directory files, I do not see how
anything is changed by the patch.

I committed the typo fix.


More information about the freebsd-fs mailing list