Whamcloud - gitweb
ChangeLog, mke2fs.8.in, mke2fs.c, tune2fs.8.in, tune2fs.c:
authorTheodore Ts'o <tytso@mit.edu>
Thu, 18 Jan 2001 01:51:15 +0000 (01:51 +0000)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 18 Jan 2001 01:51:15 +0000 (01:51 +0000)
  tune2fs.c, mke2fs.c, tune2fs.8.in, mke2fs.8.in: Change user interface
   so that -J is used to specify journal options, and -j is used to
   request creation of a journal using default values.  (This is a UI
   change, but we haven't done a formal release, and it makes things much
   more consistent with the rest of the options out there.)
  tune2fs.c: Add support for removing a filesystem from an external
   journal; we correctly remove the filesystem UUID from the external
   journal's filesystem list.

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

index 1a3ffd1..10e5e9d 100644 (file)
@@ -1,5 +1,16 @@
 2001-01-17  Theodore Ts'o  <tytso@valinux.com>
 
+       * tune2fs.c, mke2fs.c, tune2fs.8.in, mke2fs.8.in: Change user
+               interface so that -J is used to specify journal options,
+               and -j is used to request creation of a journal using
+               default values.  (This is a UI change, but we haven't done
+               a formal release, and it makes things much more consistent
+               with the rest of the options out there.) 
+
+       * tune2fs.c: Add support for removing a filesystem from an
+               external journal; we correctly remove the filesystem UUID
+               from the external journal's filesystem list.
+
        * util.h, util.c (journal_default_size): New function from Andreas
                Dilger to calculate an appropriate default journal size
                given a filesystem size.
index f8d5fe0..76cb246 100644 (file)
@@ -30,6 +30,9 @@ mke2fs \- create a Linux second extended file system
 ]
 [
 .B \-j
+]
+[
+.B \-J
 .I journal-options
 ]
 [
@@ -135,29 +138,41 @@ 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
+filesystem after it is created, so be careful deciding the correct
 value for this parameter. 
-.TP
-.BI \-j " journal options"
+.TP 
+.B -j
 Build the ext2 filesystem with the ext3 journaling feature enabled.  
+If the 
+.B \-J
+option is not specified, the default journal parameters will used will create
+an appropriately sized journal (given the size of the filesystem) 
+stored internally in the filesystem.
+.TP
+.BI \-J " journal options"
+Create the ext3 journal using options specified on the command-line.
 Journal options are comma
 separated, and may take an argument using the equals ('=')  sign.
-Currently two options are supported,
+Currently two (mutually exclusive) options are supported,
 .I size
 and
 .IR device .
-One 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 (external 
-to the filesystem) which will contain the external journal.  
+.TP
+.BI "\-J size=" journal-size
+Create a journal stored in the filesystem of size
+.IR journal-size .
+The size of the journal must be between 1MB and 100MB and it must fit within 
+the newly created filesystem.
+.TP
+.BI "\-J device=" external-journal
+Add an external journal found on a block device
+named by 
+.I external-journal 
+to the filesystem.
+The external 
+journal must have been already created using the command
+.B mke2fs -O journal_dev 
+.IR journal-device.
 .TP
 .B \-n
 causes mke2fs to not actually create a filesystem, but display what it 
index a52d632..e3cb97c 100644 (file)
@@ -88,7 +88,7 @@ int sync_kludge;      /* Set using the MKE2FS_SYNC env. option */
 static void usage(void)
 {
        fprintf(stderr, _("Usage: %s [-c|-t|-l filename] [-b block-size] "
-       "[-f fragment-size]\n\t[-i bytes-per-inode] [-j journal-options]"
+       "[-f fragment-size]\n\t[-i bytes-per-inode] [-j] [-J journal-options]"
        " [-N number-of-inodes]\n\t[-m reserved-blocks-percentage] "
        "[-o creator-os] [-g blocks-per-group]\n\t[-L volume-label] "
        "[-M last-mounted-directory] [-O feature[,...]]\n\t"
@@ -137,6 +137,7 @@ struct mke2fs_defaults {
        { default_str, 0, 4096, 8192 },
        { default_str, 512, 1024, 4096 },
        { default_str, 3, 1024, 8192 },
+       { "journal", 0, 4096, 8192 },
        { "news", 0, 4096, 4096 },
        { "largefile", 0, 4096, 1024 * 1024 },
        { "largefile4", 0, 4096, 4096 * 1024 },
@@ -569,6 +570,8 @@ static void create_journal_dev(ext2_filsys fs)
        struct progress_struct progress;
        errcode_t               retval;
        char                    *buf;
+       blk_t                   blk;
+       int                     count;
 
        if (quiet)
                memset(&progress, 0, sizeof(progress));
@@ -576,7 +579,6 @@ static void create_journal_dev(ext2_filsys fs)
                progress_init(&progress, _("Zeroing journal device: "),
                              fs->super->s_blocks_count);
 
-#if 0
        retval = zero_blocks(fs, 0, fs->super->s_blocks_count,
                             &progress, &blk, &count);
        if (retval) {
@@ -585,8 +587,8 @@ static void create_journal_dev(ext2_filsys fs)
                        blk, count);
                exit(1);
        }
-       zero_blocks(0, 0, 0, 0, 0);
-#endif
+       zero_blocks(0, 0, 0, 0, 0, 0);
+
        retval = ext2fs_create_journal_superblock(fs,
                                  fs->super->s_blocks_count, 0, &buf);
        if (retval) {
@@ -594,7 +596,9 @@ static void create_journal_dev(ext2_filsys fs)
                        _("while initialization journal superblock"));
                exit(1);
        }
-       retval = io_channel_write_blk(fs->io, 1, 1, buf);
+       retval = io_channel_write_blk(fs->io,
+                                     fs->super->s_first_data_block+1,
+                                     1, buf);
        if (retval) {
                com_err("create_journal_dev", retval,
                        _("while writing journal superblock"));
@@ -742,7 +746,7 @@ static void parse_raid_opts(const char *opts)
 }      
 
 static __u32 ok_features[3] = {
-       0,                                      /* Compat */
+       EXT3_FEATURE_COMPAT_HAS_JOURNAL,        /* Compat */
        EXT2_FEATURE_INCOMPAT_FILETYPE|         /* Incompat */
                EXT3_FEATURE_INCOMPAT_JOURNAL_DEV,
        EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER     /* R/O compat */
@@ -762,9 +766,7 @@ static void PRS(int argc, char *argv[])
        errcode_t       retval;
        int             sparse_option = 1;
        char *          oldpath = getenv("PATH");
-       struct ext2_super_block *param_ext2 = &param;
        char *          raid_opts = 0;
-       char *          journal_opts = 0;
        char *          fs_type = 0;
        const char *    feature_set = "filetype";
        blk_t           dev_size;
@@ -808,7 +810,7 @@ static void PRS(int argc, char *argv[])
        if (argc && *argv)
                program_name = *argv;
        while ((c = getopt (argc, argv,
-                   "b:cf:g:i:j:l:m:no:qr:R:s:tvI:ST:FL:M:N:O:V")) != EOF)
+                   "b:cf:g:i:jl:m:no:qr:R:s:tvI:J:ST:FL:M:N:O:V")) != EOF)
                switch (c) {
                case 'b':
                        blocksize = strtoul(optarg, &tmp, 0);
@@ -860,8 +862,12 @@ static void PRS(int argc, char *argv[])
                                exit(1);
                        }
                        break;
+               case 'J':
+                       parse_journal_opts(optarg);
+                       break;
                case 'j':
-                       journal_opts = optarg;
+                       if (!journal_size)
+                               journal_size = -1;
                        break;
                case 'l':
                        bad_blocks_filename = malloc(strlen(optarg)+1);
@@ -956,9 +962,17 @@ static void PRS(int argc, char *argv[])
        if (raid_opts)
                parse_raid_opts(raid_opts);
 
-       if (journal_opts)
-               parse_journal_opts(journal_opts);
-       
+       /* Parse the user-supplied feature_set, if any. */
+       if (feature_set && !strncasecmp(feature_set, "none", 4))
+               feature_set = NULL;
+       if (feature_set && e2p_edit_feature(feature_set,
+                                           &param.s_feature_compat,
+                                           ok_features)) {
+               fprintf(stderr, _("Invalid filesystem option set: %s\n"),
+                       feature_set);
+               exit(1);
+       }
+
        if (!force)
                check_plausibility(device_name);
        check_mount(device_name, force, _("filesystem"));
@@ -1006,7 +1020,17 @@ static void PRS(int argc, char *argv[])
                proceed_question();
        }
 
-       set_fs_defaults(fs_type, param_ext2, blocksize, &inode_ratio);
+       /*
+        * If the user asked for HAS_JOURNAL, then make sure a journal
+        * gets created.
+        */
+       if ((param.s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
+           !journal_size)
+               journal_size = -1;
+       if (!fs_type &&
+           (param.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV))
+               fs_type = "journal";
+       set_fs_defaults(fs_type, &param, blocksize, &inode_ratio);
 
        if (param.s_blocks_per_group) {
                if (param.s_blocks_per_group < 256 ||
@@ -1035,18 +1059,9 @@ static void PRS(int argc, char *argv[])
                feature_set = NULL;
        }
        if (sparse_option)
-               param_ext2->s_feature_ro_compat |=
+               param.s_feature_ro_compat |=
                        EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
 
-       if (feature_set && !strncasecmp(feature_set, "none", 4))
-               feature_set = NULL;
-       if (feature_set && e2p_edit_feature(feature_set,
-                                           &param_ext2->s_feature_compat,
-                                           ok_features)) {
-               fprintf(stderr, _("Invalid filesystem option set: %s\n"),
-                       feature_set);
-               exit(1);
-       }
 }
                                        
 int main (int argc, char *argv[])
@@ -1169,7 +1184,6 @@ int main (int argc, char *argv[])
 #endif
        }
 
-       journal_blocks = journal_size * 1024 / (fs->blocksize   / 1024);
        if (journal_device) {
                ext2_filsys     jfs;
                
@@ -1200,6 +1214,11 @@ int main (int argc, char *argv[])
                        printf(_("done\n"));
                ext2fs_close(jfs);
        } else if (journal_size) {
+               if (journal_size < 0)
+                       journal_blocks = journal_default_size(fs->super->s_blocks_count);
+               else
+                       journal_blocks = journal_size * 1024 /
+                               (fs->blocksize  / 1024);
                if (!quiet)
                        printf(_("Creating journal (%d blocks): "),
                               journal_blocks);
index b3d030e..4c07018 100644 (file)
@@ -24,6 +24,9 @@ tune2fs \- adjust tunable filesystem parameters on second extended filesystems
 ]
 [
 .B \-j
+]
+[
+.B \-J
 .I journal-options
 ]
 [
@@ -106,26 +109,39 @@ in months, and
 .B w
 in weeks.  A value of zero will disable the timedependent checking.
 .TP
-.BR \-j " journal_options"
+.B -j
+Add an ext3 journal to the filesystem.
+If the 
+.B \-J
+option is not specified, the default journal parameters will used will create
+an appropriately sized journal (given the size of the filesystem) 
+stored within the filesystem.
+.TP
+.BR \-J " journal_options"
 add a journal inode or device to the filesystem.  
 Journal options are comma
 separated, and may take an argument using the equals ('=')  sign.
-Currently two options are supported,
+Currently only two (mutually exclusive) options are supported,
 .I size
 and
 .IR device .
-One 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 (external 
-to the filesystem) which will contain the external journal.  
+.TP
+.BI "\-J size=" journal-size
+Create a journal stored in the filesystem of size
+.IR journal-size .
+The size of the journal must be between 1MB and 100MB and there 
+must be sufficient free space in the filesystem to create a journal of
+that size.
+.TP
+.BI "\-J device=" external-journal
+Add an external journal found on a block device
+named by 
+.I external-journal 
+to the filesystem.
+The external 
+journal must have been already created using the command
+.B mke2fs -O journal_dev 
+.IR journal-device.
 .TP
 .B \-l
 list the contents of the filesystem superblock.
index ebdc6ce..8827605 100644 (file)
@@ -48,6 +48,7 @@ extern int optind;
 #include "et/com_err.h"
 #include "uuid/uuid.h"
 #include "e2p/e2p.h"
+#include "jfs_user.h"
 #include "util.h"
 
 #include "../version.h"
@@ -56,7 +57,6 @@ extern int optind;
 const char * program_name = "tune2fs";
 char * device_name;
 char * new_label, *new_last_mounted, *new_UUID;
-const char *journal_opts;
 static int c_flag, C_flag, e_flag, g_flag, i_flag, l_flag, L_flag;
 static int m_flag, M_flag, r_flag, s_flag = -1, u_flag, U_flag;
 static int print_label;
@@ -77,7 +77,7 @@ static void usage(void)
        fprintf(stderr,
                _("Usage: %s [-c max-mounts-count] [-e errors-behavior] "
                  "[-g group]\n"
-                "\t[-i interval[d|m|w]] [-j journal-options]\n"
+                "\t[-i interval[d|m|w]] [-j] [-J journal-options]\n"
                 "\t[-l] [-s sparse-flag] [-m reserved-blocks-percent]\n"
                  "\t[-r reserved-blocks-count] [-u user] [-C mount-count]\n"
                  "\t[-L volume-label] [-M last-mounted-dir] [-U UUID]\n"
@@ -92,6 +92,80 @@ static __u32 ok_features[3] = {
 };
 
 /*
+ * Remove an external journal from the filesystem
+ */
+static void remove_journal_device(ext2_filsys fs)
+{
+       char            *journal_device;
+       ext2_filsys     jfs;
+       char            buf[1024];
+       journal_superblock_t    *jsb;
+       int             i, nr_users;
+       errcode_t       retval;
+
+       journal_device = ext2fs_find_block_device(fs->super->s_journal_dev);
+       if (!journal_device)
+               return;
+
+       retval = ext2fs_open(journal_device, EXT2_FLAG_RW|
+                            EXT2_FLAG_JOURNAL_DEV_OK, 0,
+                            fs->blocksize, unix_io_manager, &jfs);
+       if (retval) {
+               com_err(program_name, retval,
+                       _("while trying to open external journal"));
+               exit(1);
+       }
+       if (!(jfs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
+               fprintf(stderr, "%s is not a journal device.\n",
+                       journal_device);
+               exit(1);
+       }
+
+       /* Get the journal superblock */
+       if ((retval = io_channel_read_blk(jfs->io, 1, -1024, buf))) {
+               com_err(program_name, retval,
+                       _("while reading journal superblock"));
+               exit(1);
+       }
+
+       jsb = (journal_superblock_t *) buf;
+       if ((jsb->s_header.h_magic != (unsigned) ntohl(JFS_MAGIC_NUMBER)) ||
+           (jsb->s_header.h_blocktype != (unsigned) ntohl(JFS_SUPERBLOCK_V2))) {
+               fprintf(stderr, _("Journal superblock not found!\n"));
+               exit(1);
+       }
+
+       /* Find the filesystem UUID */
+       nr_users = ntohl(jsb->s_nr_users);
+       for (i=0; i < nr_users; i++) {
+               if (memcmp(fs->super->s_uuid,
+                          &jsb->s_users[i*16], 16) == 0)
+                       break;
+       }
+       if (i >= nr_users) {
+               fprintf(stderr, "Filesystem's UUID not found on journal device.\n");
+               exit(1);
+       }
+       nr_users--;
+       for (i=0; i < nr_users; i++)
+               memcpy(&jsb->s_users[i*16], &jsb->s_users[(i+1)*16], 16);
+       jsb->s_nr_users = htonl(nr_users);
+
+       /* Write back the journal superblock */
+       if ((retval = io_channel_write_blk(jfs->io, 1, -1024, buf))) {
+               com_err(program_name, retval,
+                       "while writing journal superblock.");
+               exit(1);
+       }
+
+       fs->super->s_journal_dev = 0;
+       memset(fs->super->s_journal_uuid, 0,
+              sizeof(fs->super->s_journal_uuid));
+       ext2fs_mark_super_dirty(fs);
+}
+
+
+/*
  * Update the feature set as provided by the user.
  */
 static void update_feature_set(ext2_filsys fs, char *features)
@@ -158,6 +232,8 @@ static void update_feature_set(ext2_filsys fs, char *features)
                                exit(1);
                        }
                }
+               if (sb->s_journal_dev)
+                       remove_journal_device(fs);
        }
        if (journal && !old_journal) {
                /*
@@ -166,12 +242,12 @@ static void update_feature_set(ext2_filsys fs, char *features)
                 * creating the journal.  We supply a default size if
                 * necessary.
                 */
-               if (!journal_opts)
-                       journal_opts = "size=16";
+               if (!journal_size)
+                       journal_size = -1;
                sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
                journal = old_journal;
        }
-       
+
        if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
            (sb->s_feature_compat || sb->s_feature_ro_compat ||
             sb->s_feature_incompat))
@@ -199,8 +275,6 @@ static void add_journal(ext2_filsys fs)
                fprintf(stderr, _("The filesystem already has a journal.\n"));
                exit(1);
        }
-       parse_journal_opts(journal_opts);
-       journal_blocks = journal_size * 1024 / (fs->blocksize / 1024);
        if (journal_device) {
                check_plausibility(journal_device);
                check_mount(journal_device, 0, _("journal"));
@@ -229,6 +303,10 @@ static void add_journal(ext2_filsys fs)
        } else if (journal_size) {
                printf(_("Creating journal inode: "));
                fflush(stdout);
+               if (journal_size < 0)
+                       journal_blocks = journal_default_size(fs->super->s_blocks_count);
+               else
+                       journal_blocks = journal_size * 1024 / (fs->blocksize / 1024);
                retval = ext2fs_add_journal_inode(fs, journal_blocks,
                                                  journal_flags);
                if (retval) {
@@ -288,7 +366,7 @@ static void parse_tune2fs_options(int argc, char **argv)
        fprintf (stderr, _("tune2fs %s, %s for EXT2 FS %s, %s\n"),
                 E2FSPROGS_VERSION, E2FSPROGS_DATE,
                 EXT2FS_VERSION, EXT2FS_DATE);
-       while ((c = getopt (argc, argv, "c:e:g:i:j:lm:r:s:u:C:L:M:O:U:")) != EOF)
+       while ((c = getopt (argc, argv, "c:e:g:i:jlm:r:s:u:C:J:L:M:O:U:")) != EOF)
                switch (c)
                {
                        case 'c':
@@ -382,7 +460,11 @@ static void parse_tune2fs_options(int argc, char **argv)
                                open_flag = EXT2_FLAG_RW;
                                break;
                        case 'j':
-                               journal_opts = optarg;
+                               if (!journal_size)
+                                       journal_size = -1;
+                               break;
+                       case 'J':
+                               parse_journal_opts(optarg);
                                open_flag = EXT2_FLAG_RW;
                                break;
                        case 'l':
@@ -606,7 +688,7 @@ int main (int argc, char ** argv)
        }
        if (features_cmd)
                update_feature_set(fs, features_cmd);
-       if (journal_opts)
+       if (journal_size || journal_device)
                add_journal(fs);
        
        if (U_flag) {