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