Date: Tue, 17 May 2016 11:20:50 +0300 From: Konstantin Belousov <kostikbel@gmail.com> To: Bruce Evans <brde@optusnet.com.au> Cc: fs@freebsd.org Subject: Re: quick fix for slow directory shrinking in ffs Message-ID: <20160517082050.GX89104@kib.kiev.ua> In-Reply-To: <20160517072705.F2157@besplex.bde.org> References: <20160517072705.F2157@besplex.bde.org>
next in thread | previous in thread | raw e-mail | index | archive | help
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.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20160517082050.GX89104>