Whamcloud - gitweb
ChangeLog, fsck.8.in, fsck.c, fsck.h, mke2fs.8.in, mke2fs.c:
authorTheodore Ts'o <tytso@mit.edu>
Mon, 19 Jul 1999 15:30:21 +0000 (15:30 +0000)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 19 Jul 1999 15:30:21 +0000 (15:30 +0000)
  * mke2fs.c (PRS, set_fs_defaults): Add new option -T which allows the
   user to specify the how the filesystem is to be used.  Mke2fs now
   chooses the filesystem parameters automatically based on the size of
   the filesystem and the intended use of the filesystem.  Add new option
   -n which simply goes through the calculations to determine the
   parameters of the filesystem the system would make.
  * fsck.c, fsck.h: Add support for new option -C.  This option will
   automatically manage e2fsck processes so that they will print
   completion/progress bars.  If multiple filesystems are being checked,
   arrange to make sure that only one e2fsck process is displaying a
   progress bar at a time.

misc/ChangeLog
misc/fsck.8.in
misc/fsck.c
misc/fsck.h
misc/mke2fs.8.in
misc/mke2fs.c

index 29415a8..4db7364 100644 (file)
@@ -1,4 +1,22 @@
-1999-07-08    <tytso@rsts-11.mit.edu>
+1999-07-18    <tytso@rsts-11.mit.edu>
+
+       * mke2fs.c (PRS, set_fs_defaults): Add new option -T which allows
+               the user to specify the how the filesystem is to be used.
+               Mke2fs now chooses the filesystem parameters automatically
+               based on the size of the filesystem and the intended use
+               of the filesystem.  Add new option -n which simply goes
+               through the calculations to determine the parameters of
+               the filesystem the system would make.
+
+1999-07-18    <tytso@valinux.com>
+
+       * fsck.c, fsck.h: Add support for new option -C.  This option will
+               automatically manage e2fsck processes so that they will
+               print completion/progress bars.  If multiple filesystems
+               are being checked, arrange to make sure that only one
+               e2fsck process is displaying a progress bar at a time.
+
+1999-07-08    <tytso@valinux.com>
 
        * badblocks.c (do_test): Don't complain if the write error occurs
                on a non-block boundary.  This is perfectly common when
index 806f378..66dda96 100644 (file)
@@ -8,32 +8,26 @@ fsck \- check and repair a Linux file system
 .SH SYNOPSIS
 .B fsck
 [
-.B \-AVRTNP
-]
-[
-.B \-s
+.B \-sACVRTNP
 ]
 [
 .B \-t
 .I fstype
-]
-[
-.B fs-options
+] -- [
+.B fsck-options
 ]
 .I filesys [ ... ]
 .SH DESCRIPTION
 .B fsck
-is used to check and optionally repair a Linux file system.  
+is used to check and optionally repair a one or more Linux file systems.  
 .I filesys
-is either the device name (e.g. /dev/hda1, /dev/sdb2) or the mount point
-(e.g. /, /usr, /home) for the file system.  If this invocation of 
+can be a device name (e.g. /dev/hda1, /dev/sdb2), a
+mount point (e.g. /, /usr, /home), or an ext2 label or UUID specifier 
+(e.g., UUID=8868abf6-88c5-4a83-98b8-bfc24057f7bd or LABEL=root).  
+The 
 .B fsck 
-has several filesystems on different physical disk drives to check, then
-.B fsck 
-will try to run them in parallel.  This reduces the total amount time it
-takes to check all of the filesystems, since 
-.B fsck
-takes advantage of the parallelism of multiple disk spindles.
+program will try to run filesystems on different physical disk drives 
+in parallel to reduce total amount time to check all of the filesystems.
 .PP
 The exit code returned by
 .B fsck
@@ -68,6 +62,48 @@ variable.  Please see the file system-specific checker manual pages for
 further details.
 .SH OPTIONS
 .TP
+.B -s
+Serialize 
+.B fsck 
+operations.  This is a good idea if you checking multiple
+filesystems and the checkers are in an interactive mode.  (Note:
+.BR e2fsck (8)
+runs in an interactive mode by default.  To make 
+.BR e2fsck (8)
+run in a non-interactive mode, you must either specify the
+.B -p
+or
+.B -a
+option, if you wish for errors to be corrected automatically, or
+the 
+.B -n
+option if you do not.)
+.TP
+.BI -t \ fstype
+Specifies the type of file system to be checked.  When the
+.B \-A 
+flag is specified, only filesystems that match 
+.I fstype
+are checked.  If 
+.I fstype
+is prefixed with 
+.B no
+then only filesystems whose type does not match
+.I fstype
+are checked.
+.sp
+Normally, the filesystem type is deduced by searching for
+.I filesys
+in the 
+.I /etc/fstab 
+file and using the corresponding entry.
+If the type can not be deduced, 
+.B fsck
+will use the type specified by the 
+.B \-t
+option if it specifies a unique filesystem type.  If this type is not
+available, then the default file system type (currently ext2) is used. 
+.TP
 .B -A
 Walk through the
 .I /etc/fstab
@@ -103,13 +139,10 @@ checks running in parallel for some reason --- for example, if the
 machine in question is short on memory so that
 excessive paging is a concern.
 .TP
-.B -R
-When checking all file systems with the
-.B \-A
-flag, skip the root file system (in case it's already mounted read-write).
-.TP
-.B -T
-Don't show the title on startup.
+.B -C
+Display completion/progress bars for those filesystems checkers (currently
+only for ext2) which support them.   Fsck will manage the filesystem checkers
+so that only one of them will display a progress bar at a time.
 .TP
 .B -N
 Don't execute, just show what would be done.
@@ -125,53 +158,19 @@ executable might be corrupted!  This option is mainly provided
 for those sysadmins who don't want to repartition the root
 filesystem to be small and compact (which is really the right solution).
 .TP
-.B -s
-Serialize 
-.B fsck 
-operations.  This is a good idea if you checking multiple
-filesystems and the checkers are in an interactive mode.  (Note:
-.BR e2fsck (8)
-runs in an interactive mode by default.  To make 
-.BR e2fsck (8)
-run in a non-interactive mode, you must either specify the
-.B -p
-or
-.B -a
-option, if you wish for errors to be corrected automatically, or
-the 
-.B -n
-option if you do not.)
+.B -R
+When checking all file systems with the
+.B \-A
+flag, skip the root file system (in case it's already mounted read-write).
+.TP
+.B -T
+Don't show the title on startup.
 .TP
 .B -V
 Produce verbose output, including all file system-specific commands
 that are executed.
 .TP
-.BI -t \ fstype
-Specifies the type of file system to be checked.  When the
-.B \-A 
-flag is specified, only filesystems that match 
-.I fstype
-are checked.  If 
-.I fstype
-is prefixed with 
-.B no
-then only filesystems whose type does not match
-.I fstype
-are checked.
-.sp
-Normally, the filesystem type is deduced by searching for
-.I filesys
-in the 
-.I /etc/fstab 
-file and using the corresponding entry.
-If the type can not be deduced, 
-.B fsck
-will use the type specified by the 
-.B \-t
-option if it specifies a unique filesystem type.  If this type is not
-available, then the default file system type (currently ext2) is used. 
-.TP
-.B fs-options
+.B fsck-options
 Any options which are not understood by 
 .BR fsck ,
 or which follow the
index db86f56..bea2995 100644 (file)
@@ -8,7 +8,7 @@
  *
  * Written by Theodore Ts'o, <tytso@mit.edu>
  * 
- * Usage:      fsck [-AVRNTM] [-s] [-t fstype] [fs-options] device
+ * Usage:      fsck [-ACVRNTM] [-s] [-t fstype] [fs-options] device
  * 
  * Miquel van Smoorenburg (miquels@drinkel.ow.org) 20-Oct-1994:
  *   o Changed -t fstype to behave like with mount when -A (all file
@@ -18,7 +18,7 @@
  *     can be added without changing this front-end.
  *   o -R flag skip root file system.
  *
- * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
+ * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999 Theodore Ts'o.
  *
  * %Begin-Header%
  * This file may be redistributed under the terms of the GNU Public
@@ -130,6 +130,7 @@ int skip_root = 0;
 int like_mount = 0;
 int notitle = 0;
 int parallel_root = 0;
+int progress = 0;
 char *progname;
 char *fstype = NULL;
 struct fs_info *filesys_info;
@@ -355,23 +356,49 @@ static char *find_fsck(char *type)
   return(s ? prog : NULL);
 }
 
+static int progress_active()
+{
+       struct fsck_instance *inst;
+
+       for (inst = instance_list; inst; inst = inst->next) {
+               if (inst->flags & FLAG_DONE)
+                       continue;
+               if (inst->flags & FLAG_PROGRESS)
+                       return 1;
+       }
+       return 0;
+}
+
 /*
  * Execute a particular fsck program, and link it into the list of
  * child processes we are waiting for.
  */
-static int execute(char *prog, char *device, char *mntpt, int interactive)
+static int execute(char *type, char *device, char *mntpt, int interactive)
 {
-       char *s, *argv[80];
+       char *s, *argv[80], prog[80];
        int  argc, i;
        struct fsck_instance *inst;
        pid_t   pid;
 
+       inst = malloc(sizeof(struct fsck_instance));
+       if (!inst)
+               return ENOMEM;
+       memset(inst, 0, sizeof(struct fsck_instance));
+
+       sprintf(prog, "fsck.%s", type);
        argv[0] = string_copy(prog);
        argc = 1;
        
        for (i=0; i <num_args; i++)
                argv[argc++] = string_copy(args[i]);
 
+       if (progress & !progress_active()) {
+               if (strcmp(type, "ext2") == 0) {
+                       argv[argc++] = "-C0";
+                       inst->flags |= FLAG_PROGRESS;
+               }
+       }
+
        argv[argc++] = string_copy(device);
        argv[argc] = 0;
 
@@ -401,12 +428,10 @@ static int execute(char *prog, char *device, char *mntpt, int interactive)
                perror(argv[0]);
                exit(EXIT_ERROR);
        }
-       inst = malloc(sizeof(struct fsck_instance));
-       if (!inst)
-               return ENOMEM;
-       memset(inst, 0, sizeof(struct fsck_instance));
+
        inst->pid = pid;
        inst->prog = string_copy(prog);
+       inst->type = string_copy(type);
        inst->device = string_copy(device);
        inst->next = instance_list;
        instance_list = inst;
@@ -422,7 +447,7 @@ static struct fsck_instance *wait_one(NOARGS)
 {
        int     status;
        int     sig;
-       struct fsck_instance *inst, *prev;
+       struct fsck_instance *inst, *inst2, *prev;
        pid_t   pid;
 
        if (!instance_list)
@@ -482,6 +507,17 @@ retry:
                prev->next = inst->next;
        else
                instance_list = inst->next;
+       if (progress && (inst->flags & FLAG_PROGRESS) &&
+           !progress_active()) {
+               for (inst2 = instance_list; inst2; inst2 = inst2->next) {
+                       if (inst2->flags & FLAG_DONE)
+                               continue;
+                       if (strcmp(inst2->type, "ext2"))
+                               continue;
+                       kill(inst2->pid, SIGUSR1);
+                       break;
+               }
+       }
        return inst;
 }
 
@@ -516,10 +552,9 @@ static int wait_all(NOARGS)
  */
 static void fsck_device(char *device, int interactive)
 {
-       const char      *type = 0;
+       char    *type = 0;
        struct fs_info *fsent;
        int retval;
-       char prog[80];
 
        if (fstype && strncmp(fstype, "no", 2) && !strchr(fstype, ','))
                type = fstype;
@@ -532,12 +567,11 @@ static void fsck_device(char *device, int interactive)
        if (!type)
                type = DEFAULT_FSTYPE;
 
-       sprintf(prog, "fsck.%s", type);
-       retval = execute(prog, device, fsent ? fsent->mountpt : 0,
+       retval = execute(type, device, fsent ? fsent->mountpt : 0,
                         interactive);
        if (retval) {
-               fprintf(stderr, "%s: Error %d while executing %s for %s\n",
-                       progname, retval, prog, device);
+               fprintf(stderr, "%s: Error %d while executing fsck.%s "
+                       "for %s\n", progname, retval, type, device);
        }
 }
 
@@ -632,15 +666,12 @@ static const char *base_device(char *device)
 static int device_already_active(char *device)
 {
        struct fsck_instance *inst;
-       const char *base;
-
-       base = base_device(device);
+       const char *base = base_device(device);
 
        for (inst = instance_list; inst; inst = inst->next) {
                if (!strcmp(base, base_device(inst->device)))
                        return 1;
        }
-
        return 0;
 }
 
@@ -742,7 +773,7 @@ static int check_all(NOARGS)
 static void usage(NOARGS)
 {
        fprintf(stderr,
-               "Usage: fsck [-AV] [-t fstype] [fs-options] filesys\n");
+               "Usage: fsck [-ACNPRTV] [-t fstype] [fs-options] filesys\n");
        exit(EXIT_USAGE);
 }
 
@@ -794,6 +825,9 @@ static void PRS(int argc, char *argv[])
                        case 'A':
                                doall++;
                                break;
+                       case 'C':
+                               progress++;
+                               break;
                        case 'V':
                                verbose++;
                                break;
index 3e13e9c..3efd954 100644 (file)
@@ -40,6 +40,7 @@ struct fs_info {
 };
 
 #define FLAG_DONE 1
+#define FLAG_PROGRESS 2
 
 /*
  * Structure to allow exit codes to be stored
@@ -49,6 +50,7 @@ struct fsck_instance {
        int     flags;
        int     exit_status;
        char *  prog;
+       char *  type;
        char *  device;
        struct fsck_instance *next;
 };
index 57423d2..4e0a3d9 100644 (file)
@@ -70,6 +70,10 @@ mke2fs \- create a Linux second extended file system
 .B \-S
 ]
 [
+.B \-T
+.I filesystem-type
+]
+[
 .B \-V
 ]
 .I device
@@ -105,9 +109,13 @@ Specify the bytes/inode ratio.
 .B mke2fs
 creates an inode for every
 .I bytes-per-inode
-bytes of space on the disk.  This value defaults to 4096 bytes.
-.I bytes-per-inode
-must be at least 1024.
+bytes of space on the disk.  
+The larger the bytes-per-inode ratio, the fewer inodes will be created.
+This value generally shouldn't be smaller than
+the blocksize of the filesystem, since then too many inodes will be made.  
+Be warned that is not possible to expand the number of inodes on a 
+filesystem after it is created, so be careful decided the correct
+value for this parameter. 
 .TP
 .I -N number-of-inodes
 overrides the default calculation of the number of inodes that should be 
@@ -189,8 +197,13 @@ and the block and inode bitmaps.  The
 program should be run immediately after this option is used, and there
 is no guarantee that any data will be salvageable.
 .TP
+.I -T fs-type
+Specify how the filesystem is going to be used, so that mke2fs can 
+automatically determine the optimal filesystem parameters.  The only
+filesystem type which is currently supported is "news".
+.TP
 .I -V
-print the version number of 
+Print the version number of 
 .B mke2fs
 and exit.
 .SH AUTHOR
index 1eb7a6e..d552993 100644 (file)
@@ -74,6 +74,7 @@ int   verbose = 0;
 int    quiet = 0;
 int    super_only = 0;
 int    force = 0;
+int    noaction = 0;
 char   *bad_blocks_filename = 0;
 __u32  fs_stride = 0;
 
@@ -187,6 +188,59 @@ static void check_mount(NOARGS)
 }
 
 /*
+ * This function sets the default parameters for a filesystem
+ *
+ * The type is specified by the user.  The size is minimum size for
+ * which a set of parameters applies, with a size of zero meaning that
+ * it is the default parameter for the type.  Note that order is
+ * important in the table below.
+ */
+static char default_str[] = "default";
+struct mke2fs_defaults {
+       char    *type;
+       int     size;
+       int     blocksize;
+       int     inode_ratio;
+} settings[] = {
+       { default_str, 0, 4096, 8192 },
+       { default_str, 512, 1024, 4096 },
+       { default_str, 3, 1024, 8192 },
+       { "news", 0, 4096, 4096 },
+       { 0, 0, 0, 0},
+};
+
+static void set_fs_defaults(char *fs_type, struct ext2fs_sb *param,
+                           int blocksize, int *inode_ratio)
+{
+       int     megs;
+       int     ratio = 0;
+       struct mke2fs_defaults *p;
+
+       megs = (param->s_blocks_count * (EXT2_BLOCK_SIZE(param) / 1024) /
+               1024);
+       if (inode_ratio)
+               ratio = *inode_ratio;
+       if (!fs_type)
+               fs_type = default_str;
+       for (p = settings; p->type; p++) {
+               if ((strcmp(p->type, fs_type) != 0) &&
+                   (strcmp(p->type, default_str) != 0))
+                       continue;
+               if ((p->size != 0) &&
+                   (megs > p->size))
+                       continue;
+               if (ratio == 0)
+                       *inode_ratio = p->inode_ratio;
+               if (blocksize == 0) {
+                       param->s_log_frag_size = param->s_log_block_size =
+                               log2(p->blocksize >> EXT2_MIN_BLOCK_LOG_SIZE);
+               }
+       }
+       if (blocksize == 0)
+               param->s_blocks_count /= EXT2_BLOCK_SIZE(param) / 1024;
+}
+
+/*
  * Helper function for read_bb_file and test_disk
  */
 static void invalid_block(ext2_filsys fs, blk_t blk)
@@ -420,6 +474,7 @@ static void create_lost_and_found(ext2_filsys fs)
        ino_t                   ino;
        const char              *name = "lost+found";
        int                     i;
+       int                     lpf_size = 0;
 
        retval = ext2fs_mkdir(fs, EXT2_ROOT_INO, 0, name);
        if (retval) {
@@ -434,6 +489,8 @@ static void create_lost_and_found(ext2_filsys fs)
        }
        
        for (i=1; i < EXT2_NDIR_BLOCKS; i++) {
+               if ((lpf_size += fs->blocksize) >= 16*1024)
+                       break;
                retval = ext2fs_expand_dir(fs, ino);
                if (retval) {
                        com_err("ext2fs_expand_dir", retval,
@@ -499,27 +556,28 @@ static void show_stats(ext2_filsys fs)
        if (param.s_blocks_count != s->s_blocks_count)
                printf("warning: %d blocks unused.\n\n",
                       param.s_blocks_count - s->s_blocks_count);
-       
+
+       memset(buf, 0, sizeof(buf));
+       strncpy(buf, s->s_volume_name, sizeof(s->s_volume_name));
+       printf("Filesystem label=%s\n", buf);
+       printf("OS type: ");
        switch (fs->super->s_creator_os) {
            case EXT2_OS_LINUX: printf ("Linux"); break;
            case EXT2_OS_HURD:  printf ("GNU/hurd");   break;
            case EXT2_OS_MASIX: printf ("Masix"); break;
            default:            printf ("(unknown os)");
         }
-       printf (" ext2 filesystem format\n");
-       memset(buf, 0, sizeof(buf));
-       strncpy(buf, s->s_volume_name, sizeof(s->s_volume_name));
-       printf("Filesystem label=%s\n", buf);
+       printf("\n");
+       printf("Block size=%u (log=%u)\n", fs->blocksize,
+               s->s_log_block_size);
+       printf("Fragment size=%u (log=%u)\n", fs->fragsize,
+               s->s_log_frag_size);
        printf("%u inodes, %u blocks\n", s->s_inodes_count,
               s->s_blocks_count);
        printf("%u blocks (%2.2f%%) reserved for the super user\n",
                s->s_r_blocks_count,
               100.0 * s->s_r_blocks_count / s->s_blocks_count);
        printf("First data block=%u\n", s->s_first_data_block);
-       printf("Block size=%u (log=%u)\n", fs->blocksize,
-               s->s_log_block_size);
-       printf("Fragment size=%u (log=%u)\n", fs->fragsize,
-               s->s_log_frag_size);
        printf("%lu block group%s\n", fs->group_desc_count,
                (fs->group_desc_count > 1) ? "s" : "");
        printf("%u blocks per group, %u fragments per group\n",
@@ -647,14 +705,16 @@ static void PRS(int argc, char *argv[])
        int     size;
        char    * tmp;
        blk_t   max = 8192;
-       int     inode_ratio = 4096;
+       int     blocksize = 0;
+       int     inode_ratio = 0;
        int     reserved_ratio = 5;
        ino_t   num_inodes = 0;
        errcode_t       retval;
-       int     sparse_option = -1;
+       int     sparse_option = 1;
        char    *oldpath = getenv("PATH");
        struct ext2fs_sb *param_ext2 = (struct ext2fs_sb *) &param;
        char    *raid_opts = 0;
+       char    *fs_type = 0;
        blk_t   dev_size;
        
        /* Update our PATH to include /sbin  */
@@ -673,6 +733,7 @@ static void PRS(int argc, char *argv[])
        setbuf(stderr, NULL);
        initialize_ext2_error_table();
        memset(&param, 0, sizeof(struct ext2_super_block));
+       param.s_rev_level = 1;  /* Create revision 1 filesystems now */
        
        fprintf (stderr, "mke2fs %s, %s for EXT2 FS %s, %s\n",
                 E2FSPROGS_VERSION, E2FSPROGS_DATE,
@@ -680,18 +741,18 @@ static void PRS(int argc, char *argv[])
        if (argc && *argv)
                program_name = *argv;
        while ((c = getopt (argc, argv,
-                           "b:cf:g:i:l:m:o:qr:R:s:tvI:SFL:M:N:V")) != EOF)
+                           "b:cf:g:i:l:m:no:qr:R:s:tvI:ST:FL:M:N:V")) != EOF)
                switch (c) {
                case 'b':
-                       size = strtoul(optarg, &tmp, 0);
-                       if (size < 1024 || size > 4096 || *tmp) {
+                       blocksize = strtoul(optarg, &tmp, 0);
+                       if (blocksize < 1024 || blocksize > 4096 || *tmp) {
                                com_err(program_name, 0, "bad block size - %s",
                                        optarg);
                                exit(1);
                        }
                        param.s_log_block_size =
-                               log2(size >> EXT2_MIN_BLOCK_LOG_SIZE);
-                       max = size * 8;
+                               log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE);
+                       max = blocksize * 8;
                        break;
                case 'c':
                case 't':       /* Check for bad blocks */
@@ -749,6 +810,9 @@ static void PRS(int argc, char *argv[])
                                exit(1);
                        }
                        break;
+               case 'n':
+                       noaction++;
+                       break;
                case 'o':
                        creator_os = optarg;
                        break;
@@ -787,6 +851,9 @@ static void PRS(int argc, char *argv[])
                case 'S':
                        super_only = 1;
                        break;
+               case 'T':
+                       fs_type = optarg;
+                       break;
                case 'V':
                        /* Print version number and exit */
                        fprintf(stderr, "\tUsing %s\n",
@@ -819,9 +886,13 @@ static void PRS(int argc, char *argv[])
 
        param.s_log_frag_size = param.s_log_block_size;
 
-       retval = ext2fs_get_device_size(device_name,
-                                       EXT2_BLOCK_SIZE(&param),
-                                       &dev_size);
+       if (noaction && param.s_blocks_count) {
+               dev_size = param.s_blocks_count;
+               retval = 0;
+       } else
+               retval = ext2fs_get_device_size(device_name,
+                                               EXT2_BLOCK_SIZE(&param),
+                                               &dev_size);
        if (retval && (retval != EXT2_ET_UNIMPLEMENTED)) {
                com_err(program_name, retval,
                        "while trying to determine filesystem size");
@@ -842,6 +913,8 @@ static void PRS(int argc, char *argv[])
                proceed_question();
        }
 
+       set_fs_defaults(fs_type, param_ext2, blocksize, &inode_ratio);
+
        if (param.s_blocks_per_group) {
                if (param.s_blocks_per_group < 256 ||
                    param.s_blocks_per_group > max || *tmp) {
@@ -929,9 +1002,12 @@ int main (int argc, char *argv[])
                        sizeof(s->s_last_mounted));
        }
        
-       if (!quiet)
+       if (!quiet || noaction)
                show_stats(fs);
 
+       if (noaction)
+               exit(0);
+
        if (bad_blocks_filename)
                read_bb_file(fs, &bb_list, bad_blocks_filename);
        if (cflag)