Whamcloud - gitweb
ChangeLog, Makefile.in, version.h:
authorTheodore Ts'o <tytso@mit.edu>
Sat, 14 Jun 1997 07:28:44 +0000 (07:28 +0000)
committerTheodore Ts'o <tytso@mit.edu>
Sat, 14 Jun 1997 07:28:44 +0000 (07:28 +0000)
  Allow people to set the version.h to something like 1.10-PLUS.
.del-inodemap.c~24510e64, main.c, resize2fs.c, resize2fs.h:
  More interim work.  All is functioning except progress meter.

ChangeLog
Makefile.in
resize/inodemap.c
resize/main.c
resize/resize2fs.c
resize/resize2fs.h
version.h

index 7d4c006..711b5db 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Sat Jun 14 03:26:45 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * Makefile.in (SRCROOT): Allow people to set the version.h to
+               something like 1.10-PLUS.
+
 Sat Jun  7 16:38:40 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
        * configure.in (rmakefile): Added (optional) private directory for
index e8cb8ef..f133302 100644 (file)
@@ -96,7 +96,7 @@ distribution_tar_file:
                > e2fsprogs-@E2FSPROGS_VERSION@-@BINARY_TYPE@.tar.gz
 
 SRCROOT = `echo e2fsprogs-@E2FSPROGS_VERSION@ | sed -e 's/-WIP//' \
-                                       -e 's/pre-//'`
+                       -e 's/pre-//' -e 's/-PLUS//'`
 
 $(srcdir)/.exclude-file:
        (cd $(srcdir)/.. ; find e2fsprogs \( -name \*~ -o -name \*.orig \
index 9dc3db2..8f419e6 100644 (file)
@@ -136,23 +136,29 @@ static ino_t inode_map_translate(inode_map imap, ino_t old)
        return 0;
 }
 
+struct istruct {
+       inode_map       imap;
+       int             flags;
+};
+
 int check_and_change_inodes(ino_t dir, int entry,
                            struct ext2_dir_entry *dirent, int offset,
                            int blocksize, char *buf, void *private)
 {
-       inode_map imap = private;
+       struct istruct *is = private;
        ino_t   new;
 
        if (!dirent->inode)
                return 0;
 
-       new = inode_map_translate(imap, dirent->inode);
+       new = inode_map_translate(is->imap, dirent->inode);
 
        if (!new)
                return 0;
-
-       printf("Inode translate (dir=%ld, name=%.*s, %ld->%ld)\n",
-              dir, dirent->name_len, dirent->name, dirent->inode, new);
+       if (is->flags & RESIZE_DEBUG_INODEMAP)
+               printf("Inode translate (dir=%ld, name=%.*s, %ld->%ld)\n",
+                      dir, dirent->name_len, dirent->name,
+                      dirent->inode, new);
 
        dirent->inode = new;
 
@@ -167,6 +173,7 @@ errcode_t ext2fs_inode_move(ext2_resize_t rfs)
        inode_map               imap;
        errcode_t               retval;
        int                     group;
+       struct istruct          is;
        
        if (rfs->old_fs->group_desc_count <=
            rfs->new_fs->group_desc_count)
@@ -222,7 +229,8 @@ errcode_t ext2fs_inode_move(ext2_resize_t rfs)
                if (LINUX_S_ISDIR(inode.i_mode))
                        rfs->new_fs->group_desc[group].bg_used_dirs_count++;
                
-               printf("inode %ld->%ld\n", ino, new);
+               if (rfs->flags & RESIZE_DEBUG_INODEMAP)
+                       printf("Inode moved %ld->%ld\n", ino, new);
 
                add_inode_map_entry(imap, ino, new);
        }
@@ -230,8 +238,10 @@ errcode_t ext2fs_inode_move(ext2_resize_t rfs)
         * Now, we iterate over all of the directories to update the
         * inode references
         */
+       is.imap = imap;
+       is.flags = rfs->flags;
        retval = ext2fs_dblist_dir_iterate(rfs->old_fs->dblist, 0, 0,
-                                          check_and_change_inodes, imap);
+                                          check_and_change_inodes, &is);
        if (retval)
                return retval;
 
index 9a53e74..3d3c589 100644 (file)
@@ -26,6 +26,7 @@ void main (int argc, char ** argv)
        errcode_t       retval;
        ext2_filsys     fs;
        int             c;
+       int             flags = 0;
        blk_t           new_size;
        io_manager      io_ptr;
 
@@ -35,11 +36,17 @@ void main (int argc, char ** argv)
        if (argc && *argv)
                program_name = *argv;
        
-       while ((c = getopt (argc, argv, "h")) != EOF) {
+       while ((c = getopt (argc, argv, "d:hp")) != EOF) {
                switch (c) {
                case 'h':
                        usage(program_name);
                        break;
+               case 'd':
+                       flags |= atoi(optarg);
+                       break;
+               case 'p':
+                       flags |= RESIZE_PERCENT_COMPLETE;
+                       break;
                default:
                        usage (program_name);
                }
@@ -49,12 +56,13 @@ void main (int argc, char ** argv)
        device_name = argv[optind++];
        new_size = atoi(argv[optind++]);
        initialize_ext2_error_table();
-#if 1
-       io_ptr = unix_io_manager;
-#else
-       io_ptr = test_io_manager;
-       test_io_backing_manager = unix_io_manager;
-#endif
+
+       if (flags & RESIZE_DEBUG_IO) {
+               io_ptr = test_io_manager;
+               test_io_backing_manager = unix_io_manager;
+       } else 
+               io_ptr = unix_io_manager;
+
        retval = ext2fs_open (device_name, EXT2_FLAG_RW, 0, 0,
                              io_ptr, &fs);
        if (retval) {
@@ -70,7 +78,7 @@ void main (int argc, char ** argv)
                ext2fs_close (fs);
                exit (1);
        }
-       retval = resize_fs(fs, new_size);
+       retval = resize_fs(fs, new_size, flags);
        if (retval) {
                com_err(program_name, retval, "while trying to resize %s",
                        device_name);
index 805a64c..b90c075 100644 (file)
@@ -8,6 +8,18 @@
  * %End-Header%
  */
 
+/*
+ * Resizing a filesystem consists of the following phases:
+ *
+ *     1.  Adjust superblock and (*) write out new parts of the inode
+ *             table
+ *     2.  Determine blocks which need to be relocated.
+ *     3.  (*) Relocate blocks which must be moved, adjusting entries
+ *             in the filesystem in the process.
+ *     4.  (*) Move inodes which must be moved (only when shrinking a
+ *             filesystem)
+ *     5.  (*) Move the inode tables, if necessary.
+ */
 #include "resize2fs.h"
 
 /*
@@ -23,7 +35,6 @@ static errcode_t adjust_superblock(ext2_resize_t rfs, blk_t new_size)
        blk_t           blk, group_block;
        unsigned long   i, j;
        struct ext2_group_desc *new;
-       char            *buf;
        int             old_numblocks, numblocks, adjblocks;
        
        fs = rfs->new_fs;
@@ -139,10 +150,10 @@ retry:
         */
        if (rfs->old_fs->group_desc_count >= fs->group_desc_count)
                return 0;
-       buf = malloc(fs->blocksize);
-       if (!buf)
+       rfs->itable_buf = malloc(fs->blocksize * fs->inode_blocks_per_group);
+       if (!rfs->itable_buf)
                return ENOMEM;
-       memset(buf, 0, fs->blocksize);
+       memset(rfs->itable_buf, 0, fs->blocksize * fs->inode_blocks_per_group);
        group_block = fs->super->s_first_data_block +
                rfs->old_fs->group_desc_count * fs->super->s_blocks_per_group;
        for (i = rfs->old_fs->group_desc_count;
@@ -181,13 +192,16 @@ retry:
                if (retval)
                        return retval;
 
-               for (blk=fs->group_desc[i].bg_inode_table, j=0;
-                    j < fs->inode_blocks_per_group;
-                    blk++, j++) {
-                       retval = io_channel_write_blk(fs->io, blk, 1, buf);
-                       if (retval)
-                               return retval;
-               }
+               /*
+                * Write out the new inode table
+                */
+               retval = io_channel_write_blk(fs->io,
+                                             fs->group_desc[i].bg_inode_table,
+                                             fs->inode_blocks_per_group,
+                                             rfs->itable_buf);
+               if (retval)
+                       return retval;
+               
                group_block += fs->super->s_blocks_per_group;
        }
        return 0;
@@ -288,9 +302,9 @@ static errcode_t determine_relocations(ext2_resize_t rfs)
                        if (blk >= (fs->group_desc[i].bg_inode_table +
                                    fs->inode_blocks_per_group))
                                continue;
-                       fs->group_desc[i].bg_inode_table = 0;
                        blk = fs->group_desc[i].bg_inode_table +
                                fs->inode_blocks_per_group - 1;
+                       fs->group_desc[i].bg_inode_table = 0;
                }
                if (fs->group_desc[i].bg_inode_table &&
                    fs->group_desc[i].bg_inode_bitmap &&
@@ -381,61 +395,94 @@ static errcode_t determine_relocations(ext2_resize_t rfs)
  */
 errcode_t move_itables(ext2_resize_t rfs)
 {
-       int     i, max;
+       int             i, n, num, max, size, diff;
        ext2_filsys     fs = rfs->new_fs;
-       char            *buf;
+       char            *cp;
        blk_t           old, new;
        errcode_t       retval, err;
 
-       printf("Hide the women and children --- "
-              "commencing inode table moves!!\n");
-       
        max = fs->group_desc_count;
        if (max > rfs->old_fs->group_desc_count)
                max = rfs->old_fs->group_desc_count;
 
-       buf = malloc(fs->blocksize * fs->inode_blocks_per_group);
-       if (!buf)
-               return ENOMEM;
+       size = fs->blocksize * fs->inode_blocks_per_group;
+       if (!rfs->itable_buf) {
+               rfs->itable_buf = malloc(size);
+               if (!rfs->itable_buf)
+                       return ENOMEM;
+       }
        
        for (i=0; i < max; i++) {
                old = rfs->old_fs->group_desc[i].bg_inode_table;
                new = fs->group_desc[i].bg_inode_table;
+               diff = new - old;
                
-               printf("Group %d block %ld->%ld\n", i, old, new);
+               if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE) 
+                       printf("Itable move group %d block "
+                              "%ld->%ld (diff %d)\n", 
+                              i, old, new, diff);
                
-               if (old == new)
+               if (!diff)
                        continue;
 
                retval = io_channel_read_blk(fs->io, old,
-                                            fs->inode_blocks_per_group, buf);
+                                            fs->inode_blocks_per_group,
+                                            rfs->itable_buf);
                if (retval) 
                        goto backout;
+               /*
+                * The end of the inode table segment often contains
+                * all zeros.  Find out if we have several blocks of
+                * zeros so we can optimize the write.
+                */
+               for (cp = rfs->itable_buf+size, n=0; n < size; n++, cp--)
+                       if (*cp)
+                               break;
+               n = n >> EXT2_BLOCK_SIZE_BITS(fs->super);
+               if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE) 
+                       printf("%d blocks of zeros...\n", n);
+               num = fs->inode_blocks_per_group;
+               if (n > diff)
+                       num -= n;
+
                retval = io_channel_write_blk(fs->io, new,
-                                             fs->inode_blocks_per_group, buf);
+                                             num, rfs->itable_buf);
                if (retval) {
                        io_channel_write_blk(fs->io, old,
-                                             fs->inode_blocks_per_group, buf);
+                                            num, rfs->itable_buf);
                        goto backout;
                }
+               if (n > diff) {
+                       retval = io_channel_write_blk(fs->io,
+                             old + fs->inode_blocks_per_group,
+                             diff, rfs->itable_buf - fs->blocksize * diff);
+                       if (retval)
+                               goto backout;
+               } 
+               io_channel_flush(fs->io);
        }
        ext2fs_flush(rfs->new_fs);
-       printf("Inode table move finished.\n");
+       if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE) 
+               printf("Inode table move finished.\n");
        return 0;
        
 backout:
-       printf("Error: %s; now backing out!\n", error_message(retval));
+       if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE) 
+               printf("Error: %s; now backing out!\n", error_message(retval));
        while (--i >= 0) {
-               printf("Group %d block %ld->%ld\n", i, new, old);
+               if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE) 
+                       printf("Group %d block %ld->%ld\n", i, new, old);
                old = rfs->old_fs->group_desc[i].bg_inode_table;
                new = fs->group_desc[i].bg_inode_table;
                
                err = io_channel_read_blk(fs->io, new,
-                                         fs->inode_blocks_per_group, buf);
+                                         fs->inode_blocks_per_group,
+                                         rfs->itable_buf);
                if (err)
                        continue;
                err = io_channel_write_blk(fs->io, old,
-                                          fs->inode_blocks_per_group, buf);
+                                          fs->inode_blocks_per_group,
+                                          rfs->itable_buf);
        }
        return retval;
 }
@@ -503,10 +550,11 @@ static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs)
 /*
  * This is the top-level routine which does the dirty deed....
  */
-errcode_t resize_fs(ext2_filsys fs, blk_t new_size)
+errcode_t resize_fs(ext2_filsys fs, blk_t new_size, int flags)
 {
        ext2_resize_t   rfs;
        errcode_t       retval;
+       int             bmove_flags;
 
        retval = ext2fs_read_bitmaps(fs);
        if (retval)
@@ -521,6 +569,8 @@ errcode_t resize_fs(ext2_filsys fs, blk_t new_size)
        memset(rfs, 0, sizeof(struct ext2_resize_struct));
 
        rfs->old_fs = fs;
+       rfs->flags = flags;
+       rfs->itable_buf  = 0;
        retval = ext2fs_dup_handle(fs, &rfs->new_fs);
        if (retval)
                goto errout;
@@ -533,49 +583,53 @@ errcode_t resize_fs(ext2_filsys fs, blk_t new_size)
        if (retval)
                goto errout;
 
-       printf("Number of free blocks: %d, Needed: %d\n",
-              fs->super->s_free_blocks_count, rfs->needed_blocks);
+       if (rfs->flags & RESIZE_DEBUG_BMOVE)
+               printf("Number of free blocks: %d, Needed: %d\n",
+                      fs->super->s_free_blocks_count, rfs->needed_blocks);
        
        if (rfs->needed_blocks > fs->super->s_free_blocks_count) {
                retval = ENOSPC;
                goto errout;
        }
-       
-       printf("\nOld superblock:\n");
-       list_super(rfs->old_fs->super);
-       printf("\n\nNew superblock:\n");
-       list_super(rfs->new_fs->super);
-       printf("\n");
 
+       bmove_flags = EXT2_BMOVE_GET_DBLIST;
+       if (rfs->flags & RESIZE_DEBUG_BMOVE)
+               bmove_flags |= EXT2_BMOVE_DEBUG;
        retval = ext2fs_move_blocks(rfs->old_fs, rfs->reserve_blocks,
-                                   rfs->new_fs->block_map,
-                                   EXT2_BMOVE_GET_DBLIST);
+                                   rfs->new_fs->block_map, bmove_flags);
        if (retval)
-               return retval;
+               goto errout;
 
        retval = ext2fs_inode_move(rfs);
        if (retval)
-               return retval;
+               goto errout;
 
        retval = move_itables(rfs);
        if (retval)
-               return retval;
+               goto errout;
 
        retval = ext2fs_calculate_summary_stats(rfs->new_fs);
        if (retval)
-               return retval;
+               goto errout;
        
        retval = ext2fs_close(rfs->new_fs);
        if (retval)
-               return retval;
+               goto errout;
+
+       rfs->flags = flags;
        
        ext2fs_free(rfs->old_fs);
+       if (rfs->itable_buf)
+               free(rfs->itable_buf);
+       free(rfs);
        
        return 0;
 
 errout:
        if (rfs->new_fs)
                ext2fs_free(rfs->new_fs);
+       if (rfs->itable_buf)
+               free(rfs->itable_buf);
        free(rfs);
        return retval;
 }
index cc50004..28297f6 100644 (file)
 #endif
 
 /*
+ * Flags for the resizer; most are debugging flags only
+ */
+#define RESIZE_DEBUG_IO                        0x0001
+#define RESIZE_DEBUG_BMOVE             0x0002
+#define RESIZE_DEBUG_INODEMAP          0x0004
+#define RESIZE_DEBUG_ITABLEMOVE                0x0008
+
+#define RESIZE_PERCENT_COMPLETE                0x0100
+
+/*
  * The core state structure for the ext2 resizer
  */
 
@@ -41,9 +51,11 @@ struct ext2_resize_struct {
        ext2_brel       block_relocate;
        ext2fs_block_bitmap reserve_blocks;
        int             needed_blocks;
+       int             flags;
+       char            *itable_buf;
 };
 
 typedef struct ext2_resize_struct *ext2_resize_t;
 
 /* prototypes */
-extern errcode_t resize_fs(ext2_filsys fs, blk_t new_size);
+extern errcode_t resize_fs(ext2_filsys fs, blk_t new_size, int flags);
index 593e11a..6104a8b 100644 (file)
--- a/version.h
+++ b/version.h
@@ -6,5 +6,5 @@
  * redistributed under the GNU Public License.
  */
 
-#define E2FSPROGS_VERSION "1.10"
-#define E2FSPROGS_DATE "24-Apr-97"
+#define E2FSPROGS_VERSION "1.10-PLUS"
+#define E2FSPROGS_DATE "12-Jun-97"