Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sbin/newfs_lfs Add "-A" option to autoconfigure the segment ...
details: https://anonhg.NetBSD.org/src/rev/d601d0c8d09a
branches: trunk
changeset: 500114:d601d0c8d09a
user: perseant <perseant%NetBSD.org@localhost>
date: Tue Dec 05 19:51:14 2000 +0000
description:
Add "-A" option to autoconfigure the segment size based on measured
bandwidth and seek time of the disk, using the "4 * bandwidth * seek
time" formula from Neefe-Matthews' 1997 paper. An RZ25 disk with this
option gets 200K segments. Reference the paper in the manual page.
diffstat:
sbin/newfs_lfs/extern.h | 3 +-
sbin/newfs_lfs/newfs.c | 92 +++++++++++++++++++++++++++++++++++++++-------
sbin/newfs_lfs/newfs_lfs.8 | 28 +++++++++----
3 files changed, 98 insertions(+), 25 deletions(-)
diffs (254 lines):
diff -r b0a3ca233e7e -r d601d0c8d09a sbin/newfs_lfs/extern.h
--- a/sbin/newfs_lfs/extern.h Tue Dec 05 18:46:10 2000 +0000
+++ b/sbin/newfs_lfs/extern.h Tue Dec 05 19:51:14 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: extern.h,v 1.3 2000/10/10 20:24:52 is Exp $ */
+/* $NetBSD: extern.h,v 1.4 2000/12/05 19:51:14 perseant Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -46,7 +46,6 @@
int make_lfs
__P((int, struct disklabel *, struct partition *, int,
int, int, int, int));
-int mkfs __P((struct partition *, char *, int, int));
extern char *progname;
extern char *special;
diff -r b0a3ca233e7e -r d601d0c8d09a sbin/newfs_lfs/newfs.c
--- a/sbin/newfs_lfs/newfs.c Tue Dec 05 18:46:10 2000 +0000
+++ b/sbin/newfs_lfs/newfs.c Tue Dec 05 19:51:14 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: newfs.c,v 1.5 2000/10/11 21:08:54 he Exp $ */
+/* $NetBSD: newfs.c,v 1.6 2000/12/05 19:51:15 perseant Exp $ */
/*-
* Copyright (c) 1989, 1992, 1993
@@ -43,7 +43,7 @@
#if 0
static char sccsid[] = "@(#)newfs.c 8.5 (Berkeley) 5/24/95";
#else
-__RCSID("$NetBSD: newfs.c,v 1.5 2000/10/11 21:08:54 he Exp $");
+__RCSID("$NetBSD: newfs.c,v 1.6 2000/12/05 19:51:15 perseant Exp $");
#endif
#endif /* not lint */
@@ -58,9 +58,11 @@
#include <sys/file.h>
#include <sys/mount.h>
#include <sys/sysctl.h>
+#include <sys/time.h>
#include <ufs/ufs/dir.h>
#include <ufs/ufs/dinode.h>
+#include <ufs/lfs/lfs.h>
#include <disktab.h>
#include <errno.h>
@@ -103,6 +105,61 @@
#endif
static void usage __P((void));
+#define CHUNKSIZE 65536
+
+static size_t
+auto_segsize(int fd, off_t len, int version)
+{
+ off_t off, bw;
+ time_t start, finish;
+ char buf[CHUNKSIZE];
+ long seeks;
+ size_t final;
+ int i;
+
+ /* First, get sequential access bandwidth */
+ time(&start);
+ finish = start;
+ for (off = 0; finish - start < 10; off += CHUNKSIZE) {
+ if (pread(fd, buf, CHUNKSIZE, off) < 0)
+ break;
+ time(&finish);
+ }
+ /* Bandwidth = bytes / sec */
+ /* printf("%ld bytes in %ld seconds\n", (long)off, (long)(finish - start)); */
+ bw = off / (finish - start);
+
+ /* Second, seek time */
+ time(&start);
+ finish = start; /* structure copy */
+ for (seeks = 0; finish - start < 10; ) {
+ off = (((double)rand()) * len) / (off_t)RAND_MAX;
+ if (pread(fd, buf, dbtob(1), off) < 0)
+ break;
+ time(&finish);
+ ++seeks;
+ }
+ /* printf("%ld seeks in %ld seconds\n", (long)seeks, (long)(finish - start)); */
+ /* Seek time in units/sec */
+ seeks /= (finish - start);
+ if (seeks == 0)
+ seeks = 1;
+
+ printf("bandwidth %ld B/s, seek time %ld ms (%ld seeks/s)\n",
+ (long)bw, 1000/seeks, seeks);
+ final = dbtob(btodb(4 * bw / seeks));
+
+ /* Version 1 filesystems have po2 segment sizes */
+ if (version == 1) {
+ for (i = 0; final; final >>= 1, i++)
+ ;
+ final = 1 << i;
+ }
+
+ printf("using initial segment size %ld\n", (long)final);
+ return final;
+}
+
int
main(argc, argv)
int argc;
@@ -112,7 +169,7 @@
struct partition *pp;
struct disklabel *lp;
struct stat st;
- int debug, force, lfs, fsi, fso, segsize, maxpartitions;
+ int debug, force, fsi, fso, segsize, maxpartitions;
char *cp, *opstring;
if ((progname = strrchr(*argv, '/')) != NULL)
@@ -124,11 +181,14 @@
if (maxpartitions > 26)
fatal("insane maxpartitions value %d", maxpartitions);
- opstring = "B:DFLNb:f:M:m:s:";
+ opstring = "AB:DFLNb:f:M:m:s:";
- debug = force = lfs = segsize = 0;
+ debug = force = segsize = 0;
while ((ch = getopt(argc, argv, opstring)) != -1)
switch(ch) {
+ case 'A': /* Adaptively configure segment size */
+ segsize = -1;
+ break;
case 'B': /* LFS segment size */
if ((segsize = atoi(optarg)) < LFS_MINSEGSIZE)
fatal("%s: bad segment size", optarg);
@@ -139,8 +199,7 @@
case 'F':
force = 1;
break;
- case 'L': /* Create lfs */
- lfs = 1;
+ case 'L': /* Compatibility only */
break;
case 'M':
minfreeseg = atoi(optarg);
@@ -153,7 +212,7 @@
disktype = optarg;
break;
#endif
- case 'b': /* used for LFS */
+ case 'b':
if ((bsize = atoi(optarg)) < LFS_MINBLOCKSIZE)
fatal("%s: bad block size", optarg);
break;
@@ -207,6 +266,7 @@
if (fstat(fsi, &st) < 0)
fatal("%s: %s", special, strerror(errno));
+
if (!debug && !S_ISCHR(st.st_mode))
(void)printf("%s: %s: not a character-special device\n",
progname, special);
@@ -241,6 +301,10 @@
pp->p_sgs = 0;
}
+ /* Try autoconfiguring segment size, if asked to */
+ if (segsize == -1)
+ segsize = auto_segsize(fsi, dbtob(pp->p_size), 1);
+
/* If we're making a LFS, we break out here */
exit(make_lfs(fso, lp, pp, minfree, bsize, fsize, segsize,
minfreeseg));
@@ -355,14 +419,14 @@
{
fprintf(stderr, "usage: newfs_lfs [ -fsoptions ] special-device\n");
fprintf(stderr, "where fsoptions are:\n");
- fprintf(stderr, "\t-B LFS segment size\n");
+ fprintf(stderr, "\t-A (autoconfigure segment size)\n");
+ fprintf(stderr, "\t-B segment size in bytes\n");
fprintf(stderr, "\t-D debug\n");
- /* fprintf(stderr, "\t-L create LFS file system\n"); */
fprintf(stderr,
- "\t-N do not create file system, just print out parameters\n");
- fprintf(stderr, "\t-b block size\n");
- fprintf(stderr, "\t-f frag size\n");
+ "\t-N (do not create file system, just print out parameters)\n");
+ fprintf(stderr, "\t-b block size in bytes\n");
+ fprintf(stderr, "\t-f frag size in bytes\n");
fprintf(stderr, "\t-m minimum free space %%\n");
- fprintf(stderr, "\t-s file system size (sectors)\n");
+ fprintf(stderr, "\t-s file system size in sectors\n");
exit(1);
}
diff -r b0a3ca233e7e -r d601d0c8d09a sbin/newfs_lfs/newfs_lfs.8
--- a/sbin/newfs_lfs/newfs_lfs.8 Tue Dec 05 18:46:10 2000 +0000
+++ b/sbin/newfs_lfs/newfs_lfs.8 Tue Dec 05 19:51:14 2000 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: newfs_lfs.8,v 1.10 2000/11/08 19:43:16 hubertf Exp $
+.\" $NetBSD: newfs_lfs.8,v 1.11 2000/12/05 19:51:15 perseant Exp $
.\"
.\" Copyright (c) 1993
.\" The Regents of the University of California. All rights reserved.
@@ -55,13 +55,15 @@
.Li fsize,
.Li bsize,
and
-.Li cpg
-(really
-.Li sgs,
-segment shift) fields are 1024, 8192, and 7 respectively.
+.Li sgs
+fields are 1024, 8192, and 7 respectively.
.Pp
The following options define the general layout policies.
.Bl -tag -width Fl
+.It Fl A
+Attempt to compute the appropriate segment size using the formula
+\fB4 * bandwidth * access time\fR. The disk is tested for twenty seconds
+to discover its bandwidth and seek time.
.It Fl B Ar logical-segment-size
The logical segment size of the file system in bytes. If not specified,
the segment size is computed by left-shifting the partition label's block
@@ -100,11 +102,9 @@
.Sh SEE ALSO
.Xr disktab 5 ,
.\" .Xr fs 5 ,
-.Xr dump_lfs 8 ,
+.Xr dumplfs 8 ,
.Xr disklabel 8 ,
-.Xr diskpart 8 ,
-.Xr lfs_cleanerd 8,
-.Xr mount_lfs 8
+.Xr diskpart 8
.\" .Xr tunefs 8
.Rs
.%A M. Seltzer
@@ -116,6 +116,16 @@
.%D January 25-29, 1993
.%P pp. 315-331
.Re
+.Rs
+.%A J. Matthews
+.%A D. Roselli
+.%A A. Costello
+.%A R. Wang
+.%A T. Anderson
+.%T "Improving the Performance of Log-Structured File Systems with Adaptive Methods"
+.%J "Proceedings of the Sixteenth ACM SOSP"
+.%D October 1997
+.Re
.Sh HISTORY
A \fBnewlfs\fR
command appeared in
Home |
Main Index |
Thread Index |
Old Index