freebsd-dev/sbin/fsck_ffs
Kirk McKusick fe5e6e2cc5 Improvement in UFS/FFS directory placement when doing mkdir(2).
The algorithm for laying out new directories was devised in the 1980s
and markedly improved the performance of the filesystem. In those days
large disks had at most 100 cylinder groups and often as few as 10-20.
Modern multi-terrabyte disks have thousands of cylinder groups. The
original algorithm does not handle these large sizes well. This change
attempts to expand the scope of the original algorithm to work well
with these much larger disks while still retaining the properties
of the original algorithm for small disks.

The filesystem implementation is divided into policy routines and
implementation routines. The policy routines can be changed in any
way desired without risk of corrupting the filesystem. The policy
requests are handled by the implementation layer. If the policy
asks for an available resource, it is granted. But if it asks for
an already in-use resource, then the implementation will provide
an available one nearby the request. Thus it is impossible for a
policy to double allocate. This change is limited to the policy
implementation.

This change updates the ffs_dirpref() routine which is responsible
for selecting the cylinder group into which a new directory should
be placed. If we are near the root of the filesystem we aim to
spread them out as much as possible. As we descend deeper from the
root we cluster them closer together around their parent as we
expect them to be more closely interactive. Higher-level directories
like usr/src/sys and usr/src/bin should be separated while the
directories in these areas are more likely to be accessed together
so should be closer. And directories within commands or kernel
subsystems should be closer still.

We pick a range of cylinder groups around the cylinder group of the
directory in which we are being created. The size of the range for
our search is based on our depth from the root of our filesystem.
We then probe that range based on how many directories are already
present. The first new directory is at 1/2 (middle) of the range;
the second is in the first 1/4 of the range, then at 3/4, 1/8, 3/8,
5/8, 7/8, 1/16, 3/16, 5/16, etc.

It is desirable to store the depth of a directory in its on-disk
inode so that it is available when we need it. We add a new field
di_dirdepth to track the depth of each directory. Because there are
few spare fields left in the inode, we choose to share an existing
field in the inode rather than having one of our own. Specifically
we create a union with the di_freelink field. The di_freelink field
is used to track inodes that have been unlinked but remain referenced.
It is not needed until a rmdir(2) operation has been done on a
directory. At that point, the directory has no contents and even
if it is kept active as a current directory is no longer able to
have any new directories or files created in it. Thus the use of
di_dirdepth and di_freelink will never coincide.

Reported by:  Timo Voelker
Reviewed by:  kib
Tested by:    Peter Holm
MFC after:    2 weeks
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D39246
2023-03-29 21:13:27 -07:00
..
dir.c Improvement in UFS/FFS directory placement when doing mkdir(2). 2023-03-29 21:13:27 -07:00
ea.c Clean up error output for extended attributes in fsck_ffs(8). 2022-11-07 14:32:42 -08:00
fsck_ffs.8 Correct the location of the first backup superblock in fsck_ffs.8. 2019-08-07 16:56:00 +00:00
fsck.h Improvement in UFS/FFS directory placement when doing mkdir(2). 2023-03-29 21:13:27 -07:00
fsutil.c Rewrite function definitions with identifier lists. 2023-03-22 15:58:18 -07:00
gjournal.c Rewrite the disk I/O management system in fsck_ffs(8). Other than 2021-01-07 15:03:15 -08:00
globs.c Move the ability to search for alternate UFS superblocks from fsck_ffs(8) 2022-08-13 12:43:40 -07:00
inode.c Improvement in UFS/FFS directory placement when doing mkdir(2). 2023-03-29 21:13:27 -07:00
main.c sys/param.h: Add _WANT_P_OSREL 2023-02-15 02:43:18 +02:00
Makefile pkgbase: Put ufs related tools and lib in their own package 2022-10-26 19:46:34 +02:00
Makefile.depend DIRDEPS_BUILD: Update dependencies. 2017-10-31 00:07:04 +00:00
pass1.c Improvement in UFS/FFS directory placement when doing mkdir(2). 2023-03-29 21:13:27 -07:00
pass1b.c Flush and close getnextino cache when done using it in Pass 1b. 2022-09-03 14:15:50 -07:00
pass2.c Improvement in UFS/FFS directory placement when doing mkdir(2). 2023-03-29 21:13:27 -07:00
pass3.c Improvement in UFS/FFS directory placement when doing mkdir(2). 2023-03-29 21:13:27 -07:00
pass4.c Rewrite the disk I/O management system in fsck_ffs(8). Other than 2021-01-07 15:03:15 -08:00
pass5.c Additional diagnostic output when running fsck_ffs with debugging flag (-d) 2022-10-30 15:00:20 -07:00
setup.c Correct several bugs in fsck_ffs(8) triggered by corrupted filesystems. 2023-03-07 15:14:47 -08:00
suj.c Rewrite function definitions with identifier lists. 2023-03-22 15:58:18 -07:00
utilities.c Remove unused includes. 2019-12-22 05:44:29 +00:00