Whamcloud - gitweb
resize2fs: Add support to use the ext4 online resize ioctl's
[tools/e2fsprogs.git] / resize / online.c
index a1c19c3..d7dc857 100644 (file)
 extern char *program_name;
 
 errcode_t online_resize_fs(ext2_filsys fs, const char *mtpt, 
-                          blk_t *new_size, int flags)
+                          blk_t *new_size, int flags EXT2FS_ATTR((unused)))
 {
+#ifdef __linux__
        struct ext2_new_group_input input;
+       struct ext4_new_group_input input64;
        struct ext2_super_block *sb = fs->super;
+       unsigned long           new_desc_blocks;
        ext2_filsys             new_fs;
        errcode_t               retval;
        dgrp_t                  i;
        blk_t                   size;
        int                     fd, r_frac, overhead;
+       int                     use_old_ioctl = 1;
 
        printf(_("Filesystem at %s is mounted on %s; "
                 "on-line resizing required\n"), fs->device_name, mtpt);
@@ -38,6 +42,25 @@ errcode_t online_resize_fs(ext2_filsys fs, const char *mtpt,
                exit(1);
        }
 
+       /*
+        * If the number of descriptor blocks is going to increase, 
+        * the on-line resizing inode must be present.
+        */
+       new_desc_blocks = ext2fs_div_ceil(
+               ext2fs_div_ceil(*new_size -
+                               fs->super->s_first_data_block,
+                               EXT2_BLOCKS_PER_GROUP(fs->super)),
+               EXT2_DESC_PER_BLOCK(fs->super));
+       printf("old desc_blocks = %lu, new_desc_blocks = %lu\n", 
+              fs->desc_blocks, new_desc_blocks);
+       if (!(fs->super->s_feature_compat & 
+             EXT2_FEATURE_COMPAT_RESIZE_INODE) &&
+           new_desc_blocks != fs->desc_blocks) {
+               com_err(program_name, 0, 
+                       _("Filesystem does not support online resizing"));
+               exit(1);
+       }
+
        fd = open(mtpt, O_RDONLY);
        if (fd < 0) {
                com_err(program_name, errno, 
@@ -52,7 +75,7 @@ errcode_t online_resize_fs(ext2_filsys fs, const char *mtpt,
                                _("Permission denied to resize filesystem"));
                else if (errno == ENOTTY)
                        com_err(program_name, 0, 
-                       _("Filesystem does not support online resizing"));
+                       _("Kernel does not support online resizing"));
                else 
                        com_err(program_name, errno, 
                        _("While checking for on-line resizing support"));
@@ -126,7 +149,21 @@ errcode_t online_resize_fs(ext2_filsys fs, const char *mtpt,
                printf("Adding group #%d\n", input.group);
 #endif
 
-               if (ioctl(fd, EXT2_IOC_GROUP_ADD, &input) < 0) {
+               if (use_old_ioctl &&
+                   ioctl(fd, EXT2_IOC_GROUP_ADD, &input) == 0)
+                       continue;
+               else
+                       use_old_ioctl = 1;
+
+               input64.group = input.group;
+               input64.block_bitmap = input.block_bitmap;
+               input64.inode_bitmap = input.inode_bitmap;
+               input64.inode_table = input.inode_table;
+               input64.blocks_count = input.blocks_count;
+               input64.reserved_blocks = input.reserved_blocks;
+               input64.unused = input.unused;
+
+               if (ioctl(fd, EXT4_IOC_GROUP_ADD, &input64) < 0) {
                        com_err(program_name, errno, 
                                _("While trying to add group #%d"), 
                                input.group);
@@ -138,4 +175,9 @@ errcode_t online_resize_fs(ext2_filsys fs, const char *mtpt,
        close(fd);
 
        return 0;
+#else
+       printf(_("Filesystem at %s is mounted on %s, and on-line resizing is"
+                "not supported on this system.\n"), fs->device_name, mtpt);
+       exit(1);
+#endif
 }