OSDN Git Service

resize2fs: fix on-line resizing
authorTheodore Ts'o <tytso@mit.edu>
Tue, 4 Oct 2011 00:35:19 +0000 (20:35 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 4 Oct 2011 00:55:34 +0000 (20:55 -0400)
On-line resizing has been broken in the 1.42 series for two reasons:
(a) the call to the new EXT4_IOC_RESIZE_FS ioctl checked for ENOTTY to
indicate that the ioctl does not exist, when in fact EINVAL is what is
returned if the ioctl doesn't exist.  (b) resize2fs was passing in a
pointer to a 64-bit value, when the ioctl expected a 32-bit value.
This was OK on little-endian systems, but it wouldn't work at all on
big-endian systems.

Fix both problems.

Addresses-Debian-Bug: #451388

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
resize/online.c

index e1d05b7..bbe684a 100644 (file)
@@ -19,6 +19,8 @@
 
 extern char *program_name;
 
+#define MAX_32_NUM ((((unsigned long long) 1) << 32) - 1)
+
 errcode_t online_resize_fs(ext2_filsys fs, const char *mtpt,
                           blk64_t *new_size, int flags EXT2FS_ATTR((unused)))
 {
@@ -31,7 +33,7 @@ errcode_t online_resize_fs(ext2_filsys fs, const char *mtpt,
        errcode_t               retval;
        double                  percent;
        dgrp_t                  i;
-       blk64_t                 size;
+       blk_t                   size;
        int                     fd, overhead;
        int                     use_old_ioctl = 1;
 
@@ -69,10 +71,8 @@ errcode_t online_resize_fs(ext2_filsys fs, const char *mtpt,
                exit(1);
        }
 
-       size=ext2fs_blocks_count(sb);
-
        if (ioctl(fd, EXT4_IOC_RESIZE_FS, new_size)) {
-               if (errno != ENOTTY) {
+               if (errno != EINVAL) {
                        if (errno == EPERM)
                                com_err(program_name, 0,
                                _("Permission denied to resize filesystem"));
@@ -87,6 +87,14 @@ errcode_t online_resize_fs(ext2_filsys fs, const char *mtpt,
                return 0;
        }
 
+       if ((ext2fs_blocks_count(sb) > MAX_32_NUM) ||
+           (*new_size > MAX_32_NUM)) {
+               com_err(program_name, 0,
+                       _("Kernel does not resizing a file system this large"));
+               exit(1);
+       }
+       size = ext2fs_blocks_count(sb);
+
        if (ioctl(fd, EXT2_IOC_GROUP_EXTEND, &size)) {
                if (errno == EPERM)
                        com_err(program_name, 0,