Whamcloud - gitweb
ChangeLog, Makefile.in, dumpe2fs.c, jfs_user.h, mke2fs.c, tune2fs.c:
authorTheodore Ts'o <tytso@mit.edu>
Tue, 16 Jan 2001 07:47:31 +0000 (07:47 +0000)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 16 Jan 2001 07:47:31 +0000 (07:47 +0000)
  tune2fs.c: Changed the external journal code so that it simply adds a
   filesystem to a journal; the journal must have bene created via
   "mke2fs -O journal_dev /dev/XXX".
  mke2fs.c: Add support for creating an external journal device by using
   the command "mke2fs -O journal_dev /dev/XXX".  Also changed the
   external journal code so -j device=/dev/XXX it simply adds a
   filesystem to that journal; the journal must have been created via
   separate step.
  dumpe2fs.c (print_journal_information): Add support for dumping
   information about an external journal device.

misc/ChangeLog
misc/Makefile.in
misc/dumpe2fs.c
misc/jfs_user.h [new file with mode: 0644]
misc/mke2fs.c
misc/tune2fs.c

index 8d85d4f..a36582f 100644 (file)
@@ -1,3 +1,18 @@
+2001-01-15  Theodore Ts'o  <tytso@valinux.com>
+
+       * tune2fs.c: Changed the external journal code so that it simply
+               adds a filesystem to a journal; the journal must have bene
+               created via "mke2fs -O journal_dev /dev/XXX".
+
+       * mke2fs.c: Add support for creating an external journal device by
+               using the command "mke2fs -O journal_dev /dev/XXX".  Also
+               changed the external journal code so -j device=/dev/XXX it
+               simply adds a filesystem to that journal; the journal must
+               have been created via separate step.
+
+       * dumpe2fs.c (print_journal_information): Add support for dumping
+               information about an external journal device.
+
 2001-01-14  Theodore Ts'o  <tytso@valinux.com>
 
        * mke2fs.c: Add new filesystem types, largefile and largefile4,
index bc76132..02d1d16 100644 (file)
@@ -87,8 +87,8 @@ lsattr: $(LSATTR_OBJS) $(DEPLIBS_E2P)
 uuidgen: $(UUIDGEN_OBJS) $(DEPLIBUUID)
        $(CC) $(ALL_LDFLAGS) -o uuidgen $(UUIDGEN_OBJS) $(LIBUUID)
 
-dumpe2fs: $(DUMPE2FS_OBJS) $(DEPLIBS_E2P)
-       $(CC) $(ALL_LDFLAGS) -o dumpe2fs $(DUMPE2FS_OBJS) $(LIBS_E2P)
+dumpe2fs: $(DUMPE2FS_OBJS) $(DEPLIBS_E2P) $(DEPLIBUUID)
+       $(CC) $(ALL_LDFLAGS) -o dumpe2fs $(DUMPE2FS_OBJS) $(LIBS_E2P) $(LIBUUID)
 
 fsck: $(FSCK_OBJS)
        $(CC) $(ALL_LDFLAGS) -o fsck $(FSCK_OBJS) $(LIBS)
index 17bf4c1..53ef32a 100644 (file)
@@ -36,6 +36,7 @@ extern int optind;
 
 #include "ext2fs/ext2fs.h"
 #include "e2p/e2p.h"
+#include "jfs_user.h"
 
 #include "../version.h"
 #include "nls-enable.h"
@@ -207,6 +208,46 @@ static int i386_byteorder(void)
        return (*cp == 1);
 }
 
+static void print_journal_information(ext2_filsys fs)
+{
+       errcode_t       retval;
+       char            buf[1024];
+       char            str[80];
+       int             i;
+       journal_superblock_t    *jsb;
+
+       /* Get the journal superblock */
+       if ((retval = io_channel_read_blk(fs->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))) {
+               com_err(program_name, 0,
+                       _("Couldn't find journal superblock magic numbers"));
+               exit(1);
+       }
+
+       fputs("\n", stdout);
+       printf("Journal block size:       %d\n", ntohl(jsb->s_blocksize));
+       printf("Journal length:           %d\n", ntohl(jsb->s_maxlen));
+       printf("Journal first block:      %d\n", ntohl(jsb->s_first));
+       printf("Journal sequence:         0x%08x\n", ntohl(jsb->s_sequence));
+       printf("Journal start:            %d\n", ntohl(jsb->s_start));
+       printf("Journal number of users:  %d\n", ntohl(jsb->s_nr_users));
+       for (i=0; i < ntohl(jsb->s_nr_users); i++) {
+               if (i)
+                       printf("                          ");
+               else
+                       printf("Journal users:            ");
+               uuid_unparse(&jsb->s_users[i*16], str);
+               printf("%s\n", str);
+       }
+}
+
 int main (int argc, char ** argv)
 {
        errcode_t       retval;
@@ -215,6 +256,7 @@ int main (int argc, char ** argv)
        int             use_superblock = 0;
        int             use_blocksize = 0;
        int             force = 0;
+       int             flags;
        int             header_only = 0;
        int             big_endian;
        int             c;
@@ -267,9 +309,11 @@ int main (int argc, char ** argv)
        device_name = argv[optind++];
        if (use_superblock && !use_blocksize)
                use_blocksize = 1024;
-       retval = ext2fs_open (device_name, force ? EXT2_FLAG_FORCE : 0,
-                             use_superblock, use_blocksize,
-                             unix_io_manager, &fs);
+       flags = EXT2_FLAG_JOURNAL_DEV_OK;
+       if (force)
+               flags |= EXT2_FLAG_FORCE;
+       retval = ext2fs_open (device_name, flags, use_superblock,
+                             use_blocksize, unix_io_manager, &fs);
        if (retval) {
                com_err (program_name, retval, _("while trying to open %s"),
                         device_name);
@@ -285,6 +329,12 @@ int main (int argc, char ** argv)
                if (big_endian)
                        printf(_("Note: This is a byte-swapped filesystem\n"));
                list_super (fs->super);
+               if (fs->super->s_feature_incompat &
+                     EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
+                       print_journal_information(fs);
+                       ext2fs_close(fs);
+                       exit(0);
+               }
                list_bad_blocks (fs);
                if (header_only) {
                        ext2fs_close (fs);
diff --git a/misc/jfs_user.h b/misc/jfs_user.h
new file mode 100644 (file)
index 0000000..17a82c7
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _JFS_USER_H
+#define _JFS_USER_H
+
+typedef unsigned short kdev_t;
+
+#include <linux/jfs.h>
+
+
+#endif /* _JFS_USER_H */
index b72ea1b..a52d632 100644 (file)
@@ -67,22 +67,23 @@ const char * program_name = "mke2fs";
 const char * device_name /* = NULL */;
 
 /* Command line options */
-int    cflag /* = 0 */ ;
-int    verbose /* = 0 */ ;
-int    quiet /* = 0 */ ;
-int    super_only /* = 0 */ ;
-int    force /* = 0 */ ;
-int    noaction /* = 0 */ ;
-int    journal_size /* = 0 */ ;
-int    journal_flags /* = 0 */ ;
-char   *bad_blocks_filename /* = 0 */ ;
-__u32  fs_stride /* = 0 */ ;
+int    cflag;
+int    verbose;
+int    quiet;
+int    super_only;
+int    force;
+int    noaction;
+int    journal_size;
+int    journal_flags;
+char   *bad_blocks_filename;
+__u32  fs_stride;
 
 struct ext2_super_block param;
-char *creator_os /* = NULL */ ;
-char *volume_label /* = NULL */ ;
-char *mount_dir /* = NULL */ ;
-char *journal_device /* = NULL */ ;
+char *creator_os;
+char *volume_label;
+char *mount_dir;
+char *journal_device;
+int sync_kludge;       /* Set using the MKE2FS_SYNC env. option */
 
 static void usage(void)
 {
@@ -307,60 +308,143 @@ _("Warning: the backup superblock/group descriptors at block %d contain\n"
        badblocks_list_iterate_end(bb_iter);
 }
 
-static void write_inode_tables(ext2_filsys fs)
-{
-       errcode_t       retval;
-       blk_t           blk;
-       int             i, j, num, count;
-       char            *buf;
-       char            format[20], backup[80];
-       int             sync_kludge = 0;
-       char            *mke2fs_sync;
+/*
+ * These functions implement a generalized progress meter.
+ */
+struct progress_struct {
+       char            format[20];
+       char            backup[80];
+       __u32           max;
+};
 
-       mke2fs_sync = getenv("MKE2FS_SYNC");
-       if (mke2fs_sync)
-               sync_kludge = atoi(mke2fs_sync);
+static void progress_init(struct progress_struct *progress,
+                         char *label,__u32 max)
+{
+       int     i;
 
-       buf = malloc(fs->blocksize * STRIDE_LENGTH);
-       if (!buf) {
-               com_err("malloc", ENOMEM,
-                       _("while allocating zeroizing buffer"));
-               exit(1);
-       }
-       memset(buf, 0, fs->blocksize * STRIDE_LENGTH);
+       memset(progress, 0, sizeof(struct progress_struct));
+       if (quiet)
+               return;
 
        /*
         * Figure out how many digits we need
         */
-       i = int_log10(fs->group_desc_count);
-       sprintf(format, "%%%dd/%%%dld", i, i);
-       memset(backup, '\b', sizeof(backup)-1);
-       backup[sizeof(backup)-1] = 0;
-       if ((2*i)+1 < sizeof(backup))
-               backup[(2*i)+1] = 0;
+       i = int_log10(max);
+       sprintf(progress->format, "%%%dd/%%%dld", i, i);
+       memset(progress->backup, '\b', sizeof(progress->backup)-1);
+       progress->backup[sizeof(progress->backup)-1] = 0;
+       if ((2*i)+1 < sizeof(progress->backup))
+               progress->backup[(2*i)+1] = 0;
+       progress->max = max;
+
+       fputs(label, stdout);
+       fflush(stdout);
+}
+
+static void progress_update(struct progress_struct *progress, __u32 val)
+{
+       if (progress->format[0] == 0)
+               return;
+       printf(progress->format, val, progress->max);
+       fputs(progress->backup, stdout);
+}
+
+static void progress_close(struct progress_struct *progress)
+{
+       if (progress->format[0] == 0)
+               return;
+       fputs(_("done                            \n"), stdout);
+}
+
+
+/*
+ * Helper function which zeros out _num_ blocks starting at _blk_.  In
+ * case of an error, the details of the error is returned via _ret_blk_
+ * and _ret_count_ if they are non-NULL pointers.  Returns 0 on
+ * success, and an error code on an error.
+ *
+ * As a special case, if the first argument is NULL, then it will
+ * attempt to free the static zeroizing buffer.  (This is to keep
+ * programs that check for memory leaks happy.)
+ */
+static errcode_t zero_blocks(ext2_filsys fs, blk_t blk, int num,
+                            struct progress_struct *progress,
+                            blk_t *ret_blk, int *ret_count)
+{
+       int             j, count, next_update, next_update_incr;
+       static char     *buf;
+       errcode_t       retval;
+
+       /* If fs is null, clean up the static buffer and return */
+       if (!fs) {
+               if (buf) {
+                       free(buf);
+                       buf = 0;
+               }
+               return 0;
+       }
+       /* Allocate the zeroizing buffer if necessary */
+       if (!buf) {
+               buf = malloc(fs->blocksize * STRIDE_LENGTH);
+               if (!buf) {
+                       com_err("malloc", ENOMEM,
+                               _("while allocating zeroizing buffer"));
+                       exit(1);
+               }
+               memset(buf, 0, fs->blocksize * STRIDE_LENGTH);
+       }
+       /* OK, do the write loop */
+       next_update = 0;
+       next_update_incr = num / 100;
+       if (next_update_incr < 1)
+               next_update_incr = 1;
+       for (j=0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH) {
+               if (num-j > STRIDE_LENGTH)
+                       count = STRIDE_LENGTH;
+               else
+                       count = num - j;
+               retval = io_channel_write_blk(fs->io, blk, count, buf);
+               if (retval) {
+                       if (ret_count)
+                               *ret_count = count;
+                       if (ret_blk)
+                               *ret_blk = blk;
+                       return retval;
+               }
+               if (progress && j > next_update) {
+                       next_update += num / 100;
+                       progress_update(progress, blk);
+               }
+       }
+       return 0;
+}      
+
+static void write_inode_tables(ext2_filsys fs)
+{
+       errcode_t       retval;
+       blk_t           blk;
+       int             i, num;
+       struct progress_struct progress;
+
+       if (quiet)
+               memset(&progress, 0, sizeof(progress));
+       else
+               progress_init(&progress, _("Writing inode tables: "),
+                             fs->group_desc_count);
 
-       if (!quiet)
-               printf(_("Writing inode tables: "));
        for (i = 0; i < fs->group_desc_count; i++) {
-               if (!quiet)
-                       printf(format, i, fs->group_desc_count);
+               progress_update(&progress, i);
                
                blk = fs->group_desc[i].bg_inode_table;
                num = fs->inode_blocks_per_group;
-               
-               for (j=0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH) {
-                       if (num-j > STRIDE_LENGTH)
-                               count = STRIDE_LENGTH;
-                       else
-                               count = num - j;
-                       retval = io_channel_write_blk(fs->io, blk, count, buf);
-                       if (retval)
-                               printf(_("Warning: could not write %d blocks "
-                                      "in inode table starting at %d: %s\n"),
-                                      count, blk, error_message(retval));
+
+               retval = zero_blocks(fs, blk, num, 0, &blk, &num);
+               if (retval) {
+                       printf(_("\nCould not write %d blocks "
+                                "in inode table starting at %d: %s\n"),
+                              num, blk, error_message(retval));
+                       exit(1);
                }
-               if (!quiet) 
-                       fputs(backup, stdout);
                if (sync_kludge) {
                        if (sync_kludge == 1)
                                sync();
@@ -368,9 +452,8 @@ static void write_inode_tables(ext2_filsys fs)
                                sync();
                }
        }
-       free(buf);
-       if (!quiet)
-               fputs(_("done                            \n"), stdout);
+       zero_blocks(0, 0, 0, 0, 0, 0);
+       progress_close(&progress);
 }
 
 static void create_root_dir(ext2_filsys fs)
@@ -480,7 +563,45 @@ static void zap_sector(ext2_filsys fs, int sect)
                printf(_("Warning: could not erase sector %d: %s\n"), sect,
                       error_message(retval));
 }
-       
+
+static void create_journal_dev(ext2_filsys fs)
+{
+       struct progress_struct progress;
+       errcode_t               retval;
+       char                    *buf;
+
+       if (quiet)
+               memset(&progress, 0, sizeof(progress));
+       else
+               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) {
+               com_err("create_journal_dev", retval,
+                       "while zeroing journal device (block %u, count %d",
+                       blk, count);
+               exit(1);
+       }
+       zero_blocks(0, 0, 0, 0, 0);
+#endif
+       retval = ext2fs_create_journal_superblock(fs,
+                                 fs->super->s_blocks_count, 0, &buf);
+       if (retval) {
+               com_err("create_journal_dev", retval,
+                       _("while initialization journal superblock"));
+               exit(1);
+       }
+       retval = io_channel_write_blk(fs->io, 1, 1, buf);
+       if (retval) {
+               com_err("create_journal_dev", retval,
+                       _("while writing journal superblock"));
+               exit(1);
+       }
+       progress_close(&progress);
+}
 
 static void show_stats(ext2_filsys fs)
 {
@@ -622,7 +743,8 @@ static void parse_raid_opts(const char *opts)
 
 static __u32 ok_features[3] = {
        0,                                      /* Compat */
-       EXT2_FEATURE_INCOMPAT_FILETYPE,         /* Incompat */
+       EXT2_FEATURE_INCOMPAT_FILETYPE|         /* Incompat */
+               EXT3_FEATURE_INCOMPAT_JOURNAL_DEV,
        EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER     /* R/O compat */
 };
 
@@ -670,6 +792,10 @@ static void PRS(int argc, char *argv[])
        } else
                putenv (PATH_SET);
 
+       tmp = getenv("MKE2FS_SYNC");
+       if (tmp)
+               sync_kludge = atoi(tmp);
+       
        setbuf(stdout, NULL);
        setbuf(stderr, NULL);
        initialize_ext2_error_table();
@@ -1009,6 +1135,13 @@ int main (int argc, char *argv[])
        if (noaction)
                exit(0);
 
+       if (fs->super->s_feature_incompat &
+           EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
+               create_journal_dev(fs);
+               ext2fs_close(fs);
+               exit(0);
+       }
+
        if (bad_blocks_filename)
                read_bb_file(fs, &bb_list, bad_blocks_filename);
        if (cflag)
@@ -1037,25 +1170,35 @@ int main (int argc, char *argv[])
        }
 
        journal_blocks = journal_size * 1024 / (fs->blocksize   / 1024);
-       if (journal_device) { 
+       if (journal_device) {
+               ext2_filsys     jfs;
+               
                if (!force)
                        check_plausibility(journal_device); 
                check_mount(journal_device, force, _("journal"));
 
+               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 journal device %s\n"),
+                               journal_device);
+                       exit(1);
+               }
                if (!quiet)
                        printf(_("Creating journal on device %s: "), 
                               journal_device);
-               retval = ext2fs_add_journal_device(fs, journal_device,
-                                                  journal_blocks,
-                                                  journal_flags);
-               if(retval) { 
+               retval = ext2fs_add_journal_device(fs, jfs);
+               if(retval) {
                        com_err (program_name, retval, 
-                                _("while trying to create journal on device %s"), 
+                                _("while trying to add journal to device %s"), 
                                 journal_device);
                        exit(1);
                }
                if (!quiet)
                        printf(_("done\n"));
+               ext2fs_close(jfs);
        } else if (journal_size) {
                if (!quiet)
                        printf(_("Creating journal (%d blocks): "),
index 81b06e0..ebdc6ce 100644 (file)
@@ -192,6 +192,7 @@ static void add_journal(ext2_filsys fs)
 {
        unsigned long journal_blocks;
        errcode_t       retval;
+       ext2_filsys     jfs;
 
        if (fs->super->s_feature_compat &
            EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
@@ -203,12 +204,20 @@ static void add_journal(ext2_filsys fs)
        if (journal_device) {
                check_plausibility(journal_device);
                check_mount(journal_device, 0, _("journal"));
+               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 journal device %s\n"),
+                               journal_device);
+                       exit(1);
+               }
                printf(_("Creating journal on device %s: "),
                       journal_device);
                fflush(stdout);
-               retval = ext2fs_add_journal_device(fs, journal_device,
-                                                  journal_blocks,
-                                                  journal_flags);
+               
+               retval = ext2fs_add_journal_device(fs, jfs);
                if (retval) {
                        com_err (program_name, retval,
                                 _("while trying to create journal on device %s"),
@@ -216,6 +225,7 @@ static void add_journal(ext2_filsys fs)
                        exit(1);
                }
                printf(_("done\n"));
+               ext2fs_close(jfs);
        } else if (journal_size) {
                printf(_("Creating journal inode: "));
                fflush(stdout);