Whamcloud - gitweb
ChangeLog, mke2fs.c:
[tools/e2fsprogs.git] / misc / tune2fs.c
index 4ecaa61..f7181c8 100644 (file)
@@ -90,17 +90,25 @@ static int strcasecmp (char *s1, char *s2)
 }
 #endif
 
-static volatile void usage (void)
+static void usage(void)
 {
-       fprintf (stderr, "Usage: %s [-c max-mounts-count] [-e errors-behavior] "
+       fprintf(stderr, "Usage: %s [-c max-mounts-count] [-e errors-behavior] "
                 "[-g group]\n"
                 "\t[-i interval[d|m|w]] [-l] [-s] [-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] "
-                "device\n", program_name);
+                "\t[-L volume-label] [-M last-mounted-dir] [-U UUID]\n"
+                "\t[-O [^]feature[,...]] device\n", program_name);
        exit (1);
 }
 
+static __u32 ok_features[3] = {
+       0,                                      /* Compat */
+       EXT2_FEATURE_INCOMPAT_FILETYPE,         /* Incompat */
+       EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER     /* R/O compat */
+};
+
+static const char *please_fsck = "Please run e2fsck on the filesystem.\n";
+
 int main (int argc, char ** argv)
 {
        int c;
@@ -111,6 +119,7 @@ int main (int argc, char ** argv)
        struct group * gr;
        struct passwd * pw;
        int open_flag = 0;
+       char *features_cmd = 0;
 
        fprintf (stderr, "tune2fs %s, %s for EXT2 FS %s, %s\n",
                 E2FSPROGS_VERSION, E2FSPROGS_DATE,
@@ -118,29 +127,27 @@ int main (int argc, char ** argv)
        if (argc && *argv)
                program_name = *argv;
        initialize_ext2_error_table();
-       while ((c = getopt (argc, argv, "c:e:g:i:lm:r:s:u:C:L:M:U:")) != EOF)
+       while ((c = getopt (argc, argv, "c:e:g:i:lm:r:s:u:C:L:M:O:U:")) != EOF)
                switch (c)
                {
                        case 'c':
                                max_mount_count = strtoul (optarg, &tmp, 0);
-                               if (*tmp || max_mount_count > 16000)
-                               {
+                               if (*tmp || max_mount_count > 16000) {
                                        com_err (program_name, 0,
                                                 "bad mounts count - %s",
                                                 optarg);
-                                       usage ();
+                                       usage();
                                }
                                c_flag = 1;
                                open_flag = EXT2_FLAG_RW;
                                break;
                        case 'C':
                                mount_count = strtoul (optarg, &tmp, 0);
-                               if (*tmp || mount_count > 16000)
-                               {
+                               if (*tmp || mount_count > 16000) {
                                        com_err (program_name, 0,
                                                 "bad mounts count - %s",
                                                 optarg);
-                                       usage ();
+                                       usage();
                                }
                                C_flag = 1;
                                open_flag = EXT2_FLAG_RW;
@@ -152,20 +159,18 @@ int main (int argc, char ** argv)
                                        errors = EXT2_ERRORS_RO;
                                else if (strcmp (optarg, "panic") == 0)
                                        errors = EXT2_ERRORS_PANIC;
-                               else
-                               {
+                               else {
                                        com_err (program_name, 0,
                                                 "bad error behavior - %s",
                                                 optarg);
-                                       usage ();
+                                       usage();
                                }
                                e_flag = 1;
                                open_flag = EXT2_FLAG_RW;
                                break;
                        case 'g':
                                resgid = strtoul (optarg, &tmp, 0);
-                               if (*tmp)
-                               {
+                               if (*tmp) {
                                        gr = getgrnam (optarg);
                                        if (gr == NULL)
                                                tmp = optarg;
@@ -174,12 +179,11 @@ int main (int argc, char ** argv)
                                                *tmp =0;
                                        }
                                }
-                               if (*tmp)
-                               {
+                               if (*tmp) {
                                        com_err (program_name, 0,
                                                 "bad gid/group name - %s",
                                                 optarg);
-                                       usage ();
+                                       usage();
                                }
                                g_flag = 1;
                                open_flag = EXT2_FLAG_RW;
@@ -208,11 +212,10 @@ int main (int argc, char ** argv)
                                        tmp++;
                                        break;
                                }
-                               if (*tmp || interval > (365 * 86400))
-                               {
+                               if (*tmp || interval > (365 * 86400)) {
                                        com_err (program_name, 0,
                                                 "bad interval - %s", optarg);
-                                       usage ();
+                                       usage();
                                }
                                i_flag = 1;
                                open_flag = EXT2_FLAG_RW;
@@ -227,12 +230,11 @@ int main (int argc, char ** argv)
                                break;
                        case 'm':
                                reserved_ratio = strtoul (optarg, &tmp, 0);
-                               if (*tmp || reserved_ratio > 50)
-                               {
+                               if (*tmp || reserved_ratio > 50) {
                                        com_err (program_name, 0,
                                                 "bad reserved block ratio - %s",
                                                 optarg);
-                                       usage ();
+                                       usage();
                                }
                                m_flag = 1;
                                open_flag = EXT2_FLAG_RW;
@@ -242,14 +244,17 @@ int main (int argc, char ** argv)
                                M_flag = 1;
                                open_flag = EXT2_FLAG_RW;
                                break;
+                       case 'O':
+                               features_cmd = optarg;
+                               open_flag = EXT2_FLAG_RW;
+                               break;
                        case 'r':
                                reserved_blocks = strtoul (optarg, &tmp, 0);
-                               if (*tmp)
-                               {
+                               if (*tmp) {
                                        com_err (program_name, 0,
                                                 "bad reserved blocks count - %s",
                                                 optarg);
-                                       usage ();
+                                       usage();
                                }
                                r_flag = 1;
                                open_flag = EXT2_FLAG_RW;
@@ -260,8 +265,7 @@ int main (int argc, char ** argv)
                                break;
                        case 'u':
                                resuid = strtoul (optarg, &tmp, 0);
-                               if (*tmp)
-                               {
+                               if (*tmp) {
                                        pw = getpwnam (optarg);
                                        if (pw == NULL)
                                                tmp = optarg;
@@ -270,12 +274,11 @@ int main (int argc, char ** argv)
                                                *tmp = 0;
                                        }
                                }
-                               if (*tmp)
-                               {
+                               if (*tmp) {
                                        com_err (program_name, 0,
                                                 "bad uid/user name - %s",
                                                 optarg);
-                                       usage ();
+                                       usage();
                                }
                                u_flag = 1;
                                open_flag = EXT2_FLAG_RW;
@@ -286,17 +289,16 @@ int main (int argc, char ** argv)
                                open_flag = EXT2_FLAG_RW;
                                break;
                        default:
-                               usage ();
+                               usage();
                }
        if (optind < argc - 1 || optind == argc)
-               usage ();
+               usage();
        if (!open_flag && !l_flag)
                usage();
        device_name = argv[optind];
        retval = ext2fs_open (device_name, open_flag, 0, 0,
                              unix_io_manager, &fs);
-        if (retval)
-       {
+        if (retval) {
                com_err (program_name, retval, "while trying to open %s",
                         device_name);
                printf("Couldn't find valid filesystem superblock.\n");
@@ -332,24 +334,20 @@ int main (int argc, char ** argv)
                         "The -g option is not supported by this version -- "
                         "Recompile with a newer kernel");
 #endif
-       if (i_flag)
-       {
+       if (i_flag) {
                fs->super->s_checkinterval = interval;
                ext2fs_mark_super_dirty(fs);
                printf ("Setting interval between check %lu seconds\n", interval);
        }
-       if (m_flag)
-       {
+       if (m_flag) {
                fs->super->s_r_blocks_count = (fs->super->s_blocks_count / 100)
                        * reserved_ratio;
                ext2fs_mark_super_dirty(fs);
                printf ("Setting reserved blocks percentage to %lu (%u blocks)\n",
                        reserved_ratio, fs->super->s_r_blocks_count);
        }
-       if (r_flag)
-       {
-               if (reserved_blocks >= fs->super->s_blocks_count)
-               {
+       if (r_flag) {
+               if (reserved_blocks >= fs->super->s_blocks_count) {
                        com_err (program_name, 0,
                                 "reserved blocks count is too big (%ul)",
                                 reserved_blocks);
@@ -364,15 +362,15 @@ int main (int argc, char ** argv)
 #ifdef EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
                if (sb->s_feature_ro_compat &
                    EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)
-                       fprintf(stderr, "\nThe filesystem already "
+                       fprintf(stderr, "\nThe filesystem already"
                                " has spare superblocks.\n");
                else {
                        sb->s_feature_ro_compat |=
                                EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
                        fs->super->s_state &= ~EXT2_VALID_FS;
                        ext2fs_mark_super_dirty(fs);
-                       printf("\nSparse superblock flag set.  "
-                              "Please run e2fsck on the filesystem.\n");
+                       printf("\nSparse superblock flag set.  %s",
+                              please_fsck);
                }
 #else /* !EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER */
                com_err (program_name, 0,
@@ -384,7 +382,7 @@ int main (int argc, char ** argv)
 #ifdef EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
                if (!(sb->s_feature_ro_compat &
                      EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))
-                       fprintf(stderr, "\nThe filesystem already "
+                       fprintf(stderr, "\nThe filesystem already"
                                " does not support spare superblocks.\n");
                else {
                        sb->s_feature_ro_compat &=
@@ -392,8 +390,8 @@ int main (int argc, char ** argv)
                        fs->super->s_state &= ~EXT2_VALID_FS;
                        fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
                        ext2fs_mark_super_dirty(fs);
-                       printf("\nSparse superblock flag cleared.  "
-                              "Please run e2fsck on the filesystem.\n");
+                       printf("\nSparse superblock flag cleared.  %s",
+                              please_fsck);
                }
 #else /* !EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER */
                com_err (program_name, 0,
@@ -415,6 +413,9 @@ int main (int argc, char ** argv)
                         "Recompile with a newer kernel");
 #endif
        if (L_flag) {
+               if (strlen(new_label) > sizeof(sb->s_volume_name))
+                       fprintf(stderr, "Warning: label too "
+                               "long, truncating.\n");
                memset(sb->s_volume_name, 0, sizeof(sb->s_volume_name));
                strncpy(sb->s_volume_name, new_label,
                        sizeof(sb->s_volume_name));
@@ -426,6 +427,31 @@ int main (int argc, char ** argv)
                        sizeof(sb->s_last_mounted));
                ext2fs_mark_super_dirty(fs);
        }
+       if (features_cmd) {
+               int sparse, old_sparse, filetype, old_filetype;
+
+               old_sparse = sb->s_feature_ro_compat &
+                       EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
+               old_filetype = sb->s_feature_incompat &
+                       EXT2_FEATURE_INCOMPAT_FILETYPE;
+               if (e2p_edit_feature(features_cmd,
+                                    &sb->s_feature_compat,
+                                    ok_features)) {
+                       fprintf(stderr, "Invalid filesystem option set: %s\n",
+                               features_cmd);
+                       exit(1);
+               }
+               sparse = sb->s_feature_ro_compat &
+                       EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
+               filetype = sb->s_feature_incompat &
+                       EXT2_FEATURE_INCOMPAT_FILETYPE;
+               if ((sparse != old_sparse) ||
+                   (filetype != old_filetype)) {
+                       fs->super->s_state &= ~EXT2_VALID_FS;
+                       printf("\n%s\n", please_fsck);
+               }
+               ext2fs_mark_super_dirty(fs);
+       }
        if (U_flag) {
                if (strcasecmp(new_UUID, "null") == 0) {
                        uuid_clear(sb->s_uuid);