diff options
author | mckusick <mckusick@FreeBSD.org> | 2013-03-22 21:45:28 +0000 |
---|---|---|
committer | mckusick <mckusick@FreeBSD.org> | 2013-03-22 21:45:28 +0000 |
commit | be2f56b8d7746e3a931d3f607c34cf88e72f901b (patch) | |
tree | 4dd79ec73ca7a215a3694baba70bbfe162604d09 /sbin/newfs | |
parent | 82edd7c36328fd70dad3a7c7b7e7f8de433ce40b (diff) | |
download | FreeBSD-src-be2f56b8d7746e3a931d3f607c34cf88e72f901b.zip FreeBSD-src-be2f56b8d7746e3a931d3f607c34cf88e72f901b.tar.gz |
The purpose of this change to the FFS layout policy is to reduce the
running time for a full fsck. It also reduces the random access time
for large files and speeds the traversal time for directory tree walks.
The key idea is to reserve a small area in each cylinder group
immediately following the inode blocks for the use of metadata,
specifically indirect blocks and directory contents. The new policy
is to preferentially place metadata in the metadata area and
everything else in the blocks that follow the metadata area.
The size of this area can be set when creating a filesystem using
newfs(8) or changed in an existing filesystem using tunefs(8).
Both utilities use the `-k held-for-metadata-blocks' option to
specify the amount of space to be held for metadata blocks in each
cylinder group. By default, newfs(8) sets this area to half of
minfree (typically 4% of the data area).
This work was inspired by a paper presented at Usenix's FAST '13:
www.usenix.org/conference/fast13/ffsck-fast-file-system-checker
Details of this implementation appears in the April 2013 of ;login:
www.usenix.org/publications/login/april-2013-volume-38-number-2.
A copy of the April 2013 ;login: paper can also be downloaded
from: www.mckusick.com/publications/faster_fsck.pdf.
Reviewed by: kib
Tested by: Peter Holm
MFC after: 4 weeks
Diffstat (limited to 'sbin/newfs')
-rw-r--r-- | sbin/newfs/mkfs.c | 6 | ||||
-rw-r--r-- | sbin/newfs/newfs.8 | 12 | ||||
-rw-r--r-- | sbin/newfs/newfs.c | 11 | ||||
-rw-r--r-- | sbin/newfs/newfs.h | 1 |
4 files changed, 29 insertions, 1 deletions
diff --git a/sbin/newfs/mkfs.c b/sbin/newfs/mkfs.c index 0a547f9..a4cfa8d 100644 --- a/sbin/newfs/mkfs.c +++ b/sbin/newfs/mkfs.c @@ -444,6 +444,12 @@ restart: if (sblock.fs_sbsize > SBLOCKSIZE) sblock.fs_sbsize = SBLOCKSIZE; sblock.fs_minfree = minfree; + if (metaspace > 0 && metaspace < sblock.fs_fpg / 2) + sblock.fs_metaspace = blknum(&sblock, metaspace); + else if (metaspace != -1) + /* reserve half of minfree for metadata blocks */ + sblock.fs_metaspace = blknum(&sblock, + (sblock.fs_fpg * minfree) / 200); if (maxbpg == 0) sblock.fs_maxbpg = MAXBLKPG(sblock.fs_bsize); else diff --git a/sbin/newfs/newfs.8 b/sbin/newfs/newfs.8 index 7cfdfd1..f40b607 100644 --- a/sbin/newfs/newfs.8 +++ b/sbin/newfs/newfs.8 @@ -50,6 +50,7 @@ .Op Fl g Ar avgfilesize .Op Fl h Ar avgfpdir .Op Fl i Ar bytes +.Op Fl k Ar held-for-metadata-blocks .Op Fl m Ar free-space .Op Fl o Ar optimization .Op Fl p Ar partition @@ -163,6 +164,17 @@ This flag is implemented by running the .Xr tunefs 8 utility found in the user's .Dv $PATH . +.It Fl k Ar held-for-metadata-blocks +Set the amount of space to be held for metadata blocks in each cylinder group. +When set, the file system preference routines will try to save +the specified amount of space immediately following the inode blocks +in each cylinder group for use by metadata blocks. +Clustering the metadata blocks speeds up random file access +and decreases the running time of +.Xr fsck 8 . +By default +.Xr newfs 8 +sets it to half of the space reserved to minfree. .It Fl l Enable multilabel MAC on the new file system. .It Fl m Ar free-space diff --git a/sbin/newfs/newfs.c b/sbin/newfs/newfs.c index 3ce0be7..59b7e61 100644 --- a/sbin/newfs/newfs.c +++ b/sbin/newfs/newfs.c @@ -102,6 +102,7 @@ int bsize = 0; /* block size */ int maxbsize = 0; /* maximum clustering */ int maxblkspercg = MAXBLKSPERCG; /* maximum blocks per cylinder group */ int minfree = MINFREE; /* free space threshold */ +int metaspace; /* space held for metadata blocks */ int opt = DEFAULTOPT; /* optimization preference (space or time) */ int density; /* number of bytes per inode */ int maxcontig = 0; /* max contiguous blocks to allocate */ @@ -141,7 +142,7 @@ main(int argc, char *argv[]) part_name = 'c'; reserved = 0; while ((ch = getopt(argc, argv, - "EJL:NO:RS:T:UXa:b:c:d:e:f:g:h:i:jlm:no:p:r:s:t")) != -1) + "EJL:NO:RS:T:UXa:b:c:d:e:f:g:h:i:jk:lm:no:p:r:s:t")) != -1) switch (ch) { case 'E': Eflag = 1; @@ -248,6 +249,13 @@ main(int argc, char *argv[]) case 'l': lflag = 1; break; + case 'k': + if ((metaspace = atoi(optarg)) < 0) + errx(1, "%s: bad metadata space %%", optarg); + if (metaspace == 0) + /* force to stay zero in mkfs */ + metaspace = -1; + break; case 'm': if ((minfree = atoi(optarg)) < 0 || minfree > 99) errx(1, "%s: bad free space %%", optarg); @@ -501,6 +509,7 @@ usage() fprintf(stderr, "\t-h average files per directory\n"); fprintf(stderr, "\t-i number of bytes per inode\n"); fprintf(stderr, "\t-j enable soft updates journaling\n"); + fprintf(stderr, "\t-k space to hold for metadata blocks\n"); fprintf(stderr, "\t-l enable multilabel MAC\n"); fprintf(stderr, "\t-n do not create .snap directory\n"); fprintf(stderr, "\t-m minimum free space %%\n"); diff --git a/sbin/newfs/newfs.h b/sbin/newfs/newfs.h index 9e1da0d..72f4314 100644 --- a/sbin/newfs/newfs.h +++ b/sbin/newfs/newfs.h @@ -96,6 +96,7 @@ extern int bsize; /* block size */ extern int maxbsize; /* maximum clustering */ extern int maxblkspercg; /* maximum blocks per cylinder group */ extern int minfree; /* free space threshold */ +extern int metaspace; /* space held for metadata blocks */ extern int opt; /* optimization preference (space or time) */ extern int density; /* number of bytes per inode */ extern int maxcontig; /* max contiguous blocks to allocate */ |