Whamcloud - gitweb
ChangeLog, mke2fs.8.in, mke2fs.c:
authorTheodore Ts'o <tytso@mit.edu>
Fri, 17 Nov 2000 04:55:24 +0000 (04:55 +0000)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 17 Nov 2000 04:55:24 +0000 (04:55 +0000)
  mke2fs.c(main): Expand the -j option so that it parses option=argument
   style options, and add support for creating filesystems with external
   journals.
  mke2fs.8.in: Document new syntax for the -j option.

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

index 6985af1..4ff38e2 100644 (file)
@@ -1,3 +1,11 @@
+2000-11-16  Theodore Ts'o  <tytso@valinux.com>
+
+       * mke2fs.c(main): Expand the -j option so that it parses
+               option=argument style options, and add support for
+               creating filesystems with external journals.
+
+       * mke2fs.8.in: Document new syntax for the -j option.
+
 2000-11-05    <tytso@snap.thunk.org>
 
        * e2image.c, Makefile.in: New program which saves ext2 metadata to
index 9c04326..f54d15f 100644 (file)
@@ -30,7 +30,7 @@ mke2fs \- create a Linux second extended file system
 ]
 [
 .B \-j
-.I megabytes-for-journal
+.I journal-options
 ]
 [
 .B \-N
@@ -138,11 +138,26 @@ 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
-.BI \-j " megabytes-for-journal"
+.BI \-j " journal options"
 Build the ext2 filesystem with the ext3 journaling feature enabled.  
-Megabyts-for-journal specifies the size of the journal in MB 
-(1024*1024 bytes).  Any size between 4MB and 100MB may be used.
-Of course, the journal must be small enough to fit into the filesystem.
+Journal options are comma
+separated, and may take an argument using the equals ('=')  sign.
+Currently two options are supported,
+.I size
+and
+.IR device .
+One of these two options must be specified when building the journal.
+The 
+.I size 
+option takes a numerical argument which specifies the size of the 
+journal in MB (1024*1024 bytes).  Any size between 4MB and 100MB may be used.
+Use of this option implies that the journal will be stored in the 
+filesystem, so it must be small enough to fit into the filesystem.
+The 
+.I device
+option takes a filename which specifies a block device which will contain 
+the journal.  This option of course implies that the journal will be 
+stored external to the filesystem.
 .TP
 .B \-n
 causes mke2fs to not actually create a filesystem, but display what it 
index a19b396..2659fd7 100644 (file)
@@ -87,8 +87,11 @@ struct ext2_super_block param;
 char *creator_os = NULL;
 char *volume_label = NULL;
 char *mount_dir = NULL;
+char *journal_device = NULL;
 
-static void usage(NOARGS), check_plausibility(NOARGS), check_mount(NOARGS);
+static void usage(NOARGS);
+static void check_plausibility(const char *device);
+static void check_mount(const char *device);
 
 static void usage(NOARGS)
 {
@@ -142,7 +145,7 @@ static void proceed_question(NOARGS)
 #define SCSI_BLK_MAJOR(M)  ((M) == SCSI_DISK_MAJOR || (M) == SCSI_CDROM_MAJOR)
 #endif
 
-static void check_plausibility(NOARGS)
+static void check_plausibility(const char *device)
 {
 #ifdef HAVE_LINUX_MAJOR_H
 #ifndef MAJOR
@@ -153,18 +156,18 @@ static void check_plausibility(NOARGS)
        int val;
        struct stat s;
        
-       val = stat(device_name, &s);
+       val = stat(device, &s);
        
        if(val == -1) {
                fprintf(stderr, _("Could not stat %s --- %s\n"),
-                       device_name, error_message(errno));
+                       device, error_message(errno));
                if (errno == ENOENT)
                        fprintf(stderr, _("\nThe device apparently does "
                               "not exist; did you specify it correctly?\n"));
                exit(1);
        }
        if(!S_ISBLK(s.st_mode)) {
-               printf(_("%s is not a block special device.\n"), device_name);
+               printf(_("%s is not a block special device.\n"), device);
                proceed_question();
                return;
        } else if ((MAJOR(s.st_rdev) == HD_MAJOR &&
@@ -172,28 +175,28 @@ static void check_plausibility(NOARGS)
                   (SCSI_BLK_MAJOR(MAJOR(s.st_rdev)) &&
                       MINOR(s.st_rdev)%16 == 0)) {
                printf(_("%s is entire device, not just one partition!\n"),
-                      device_name);
+                      device);
                proceed_question();
        }
 #endif
 }
 
-static void check_mount(NOARGS)
+static void check_mount(const char *device)
 {
        errcode_t       retval;
        int             mount_flags;
 
-       retval = ext2fs_check_if_mounted(device_name, &mount_flags);
+       retval = ext2fs_check_if_mounted(device, &mount_flags);
        if (retval) {
                com_err("ext2fs_check_if_mount", retval,
                        _("while determining whether %s is mounted."),
-                       device_name);
+                       device);
                return;
        }
        if (!(mount_flags & EXT2_MF_MOUNTED))
                return;
 
-       fprintf(stderr, _("%s is mounted; "), device_name);
+       fprintf(stderr, _("%s is mounted; "), device);
        if (force) {
                fprintf(stderr, _("mke2fs forced anyway.  "
                        "Hope /etc/mtab is incorrect.\n"));
@@ -719,6 +722,76 @@ static void parse_raid_opts(const char *opts)
        }
 }      
 
+static void parse_journal_opts(const char *opts)
+{
+       char    *buf, *token, *next, *p, *arg;
+       int     len;
+       int     journal_usage = 0;
+
+       len = strlen(opts);
+       buf = malloc(len+1);
+       if (!buf) {
+               fprintf(stderr, _("Couldn't allocate memory to parse "
+                       "journal options!\n"));
+               exit(1);
+       }
+       strcpy(buf, opts);
+       for (token = buf; token && *token; token = next) {
+               p = strchr(token, ',');
+               next = 0;
+               if (p) {
+                       *p = 0;
+                       next = p+1;
+               } 
+               arg = strchr(token, '=');
+               if (arg) {
+                       *arg = 0;
+                       arg++;
+               }
+               printf("Journal option=%s, argument=%s\n", token,
+                      arg ? arg : "NONE");
+               if (strcmp(token, "device") == 0) {
+                       if (!arg) {
+                               journal_usage++;
+                               continue;
+                       }
+                       journal_device = arg;
+               } else if (strcmp(token, "size") == 0) {
+                       if (!arg) {
+                               journal_usage++;
+                               continue;
+                       }
+                       journal_size = strtoul(arg, &p, 0);
+               journal_size_check:
+                       if (*p || (journal_size < 4 || journal_size > 100)) {
+                               fprintf(stderr,
+                               _("Invalid journal size parameter - %s.\n"),
+                                       arg);
+                               journal_usage++;
+                               continue;
+                       }
+               } else {
+                       journal_size = strtoul(token, &p, 0);
+                       if (*p)
+                               journal_usage++;
+                       else
+                               goto journal_size_check;
+               }
+       }
+       if (journal_usage) {
+               fprintf(stderr, _("\nBad journal options specified.\n\n"
+                       "Journal options are separated by commas, "
+                       "and may take an argument which\n"
+                       "\tis set off by an equals ('=') sign.\n\n"
+                       "Valid raid options are:\n"
+                       "\tsize=<journal size in megabytes>\n"
+                       "\tdevice=<journal device>\n\n"
+                       "Journal size must be between "
+                       "4 and 100 megabytes.\n\n" ));
+               exit(1);
+       }
+}      
+
 static __u32 ok_features[3] = {
        0,                                      /* Compat */
        EXT2_FEATURE_INCOMPAT_FILETYPE,         /* Incompat */
@@ -741,6 +814,7 @@ static void PRS(int argc, char *argv[])
        char *          oldpath = getenv("PATH");
        struct ext2fs_sb *param_ext2 = (struct ext2fs_sb *) &param;
        char *          raid_opts = 0;
+       char *          journal_opts = 0;
        char *          fs_type = 0;
        const char *    feature_set = "filetype";
        blk_t           dev_size;
@@ -833,12 +907,16 @@ static void PRS(int argc, char *argv[])
                        }
                        break;
                case 'j':
+                       journal_opts = optarg;
+                       break;
+#if 0
                        journal_size = strtoul(optarg, &tmp, 0);
                        if (journal_size < 4 || journal_size > 100 || *tmp) {
                                com_err(program_name, 0,
                                        _("bad journal size - %s"), optarg);
                                exit(1);
                        }
+#endif
                        break;
                case 'l':
                        bad_blocks_filename = malloc(strlen(optarg)+1);
@@ -933,9 +1011,12 @@ static void PRS(int argc, char *argv[])
        if (raid_opts)
                parse_raid_opts(raid_opts);
 
+       if (journal_opts)
+               parse_journal_opts(journal_opts);
+       
        if (!force)
-               check_plausibility();
-       check_mount();
+               check_plausibility(device_name);
+       check_mount(device_name);
 
        param.s_log_frag_size = param.s_log_block_size;
 
@@ -1125,7 +1206,25 @@ int main (int argc, char *argv[])
                zap_sector(fs, 0);
 #endif
        }
-       if (journal_size) {
+
+       if (journal_device) { 
+               if (!force)
+                       check_plausibility(journal_device); 
+               check_mount(journal_device);
+
+               if (!quiet)
+                       printf(_("Creating journal on device %s: "), 
+                              journal_device);
+               retval = ext2fs_add_journal_device(fs, journal_device, 0);
+               if(retval) { 
+                       com_err (program_name, retval, 
+                                _("while trying to create journal on device %s"), 
+                                journal_device);
+                       exit(1);
+               }
+               if (!quiet)
+                       printf(_("done\n"));
+       } else if (journal_size) {
                if (!quiet)
                        printf(_("Creating journal: "));
                journal_blocks = journal_size * 1024 /