Whamcloud - gitweb
Fix various gcc -Wall nits. Fixed a bug in mke2fs where a bogus
[tools/e2fsprogs.git] / misc / tune2fs.c
1 /*
2  * tune2fs.c - Change the file system parameters on an ext2 file system
3  *
4  * Copyright (C) 1992, 1993, 1994  Remy Card <card@masi.ibp.fr>
5  *                                 Laboratoire MASI, Institut Blaise Pascal
6  *                                 Universite Pierre et Marie Curie (Paris VI)
7  *
8  * Copyright 1995, 1996, 1997, 1998, 1999, 2000 by Theodore Ts'o.
9  *
10  * %Begin-Header%
11  * This file may be redistributed under the terms of the GNU Public
12  * License.
13  * %End-Header%
14  */
15
16 /*
17  * History:
18  * 93/06/01     - Creation
19  * 93/10/31     - Added the -c option to change the maximal mount counts
20  * 93/12/14     - Added -l flag to list contents of superblock
21  *                M.J.E. Mol (marcel@duteca.et.tudelft.nl)
22  *                F.W. ten Wolde (franky@duteca.et.tudelft.nl)
23  * 93/12/29     - Added the -e option to change errors behavior
24  * 94/02/27     - Ported to use the ext2fs library
25  * 94/03/06     - Added the checks interval from Uwe Ohse (uwe@tirka.gun.de)
26  */
27
28 #include <fcntl.h>
29 #include <grp.h>
30 #ifdef HAVE_GETOPT_H
31 #include <getopt.h>
32 #else
33 extern char *optarg;
34 extern int optind;
35 #endif
36 #include <pwd.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <time.h>
41 #include <unistd.h>
42 #include <sys/types.h>
43
44 #include "ext2fs/ext2_fs.h"
45 #include "ext2fs/ext2fs.h"
46 #include "et/com_err.h"
47 #include "uuid/uuid.h"
48 #include "e2p/e2p.h"
49 #include "jfs_user.h"
50 #include "util.h"
51 #include "get_device_by_label.h"
52
53 #include "../version.h"
54 #include "nls-enable.h"
55
56 const char * program_name = "tune2fs";
57 char * device_name;
58 char * new_label, *new_last_mounted, *new_UUID;
59 static int c_flag, C_flag, e_flag, f_flag, g_flag, i_flag, l_flag, L_flag;
60 static int m_flag, M_flag, r_flag, s_flag = -1, u_flag, U_flag;
61 static int print_label;
62 static int max_mount_count, mount_count, mount_flags;
63 static unsigned long interval, reserved_ratio, reserved_blocks;
64 static unsigned long resgid, resuid;
65 static unsigned short errors;
66 static int open_flag;
67 static char *features_cmd;
68
69 int journal_size, journal_flags;
70 char *journal_device;
71
72 static const char *please_fsck = N_("Please run e2fsck on the filesystem.\n");
73
74 static void usage(void)
75 {
76         fprintf(stderr,
77                 _("Usage: %s [-c max-mounts-count] [-e errors-behavior] "
78                   "[-g group]\n"
79                  "\t[-i interval[d|m|w]] [-j] [-J journal-options]\n"
80                  "\t[-l] [-s sparse-flag] [-m reserved-blocks-percent]\n"
81                   "\t[-r reserved-blocks-count] [-u user] [-C mount-count]\n"
82                   "\t[-L volume-label] [-M last-mounted-dir] [-U UUID]\n"
83                   "\t[-O [^]feature[,...]] device\n"), program_name);
84         exit (1);
85 }
86
87 static __u32 ok_features[3] = {
88         EXT3_FEATURE_COMPAT_HAS_JOURNAL,        /* Compat */
89         EXT2_FEATURE_INCOMPAT_FILETYPE,         /* Incompat */
90         EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER     /* R/O compat */
91 };
92
93 /*
94  * Remove an external journal from the filesystem
95  */
96 static void remove_journal_device(ext2_filsys fs)
97 {
98         char            *journal_path;
99         ext2_filsys     jfs;
100         char            buf[1024];
101         journal_superblock_t    *jsb;
102         int             i, nr_users;
103         errcode_t       retval;
104         int             commit_remove_journal = 0;
105
106         if (f_flag)
107                 commit_remove_journal = 1; /* force removal even if error */
108
109         uuid_unparse(fs->super->s_journal_uuid, buf);
110         journal_path = get_spec_by_uuid(buf);
111
112         if (!journal_path) {
113                 journal_path =
114                         ext2fs_find_block_device(fs->super->s_journal_dev);
115                 if (!journal_path)
116                         return;
117         }
118
119         retval = ext2fs_open(journal_path, EXT2_FLAG_RW|
120                              EXT2_FLAG_JOURNAL_DEV_OK, 0,
121                              fs->blocksize, unix_io_manager, &jfs);
122         if (retval) {
123                 com_err(program_name, retval,
124                         _("while trying to open external journal"));
125                 goto no_valid_journal;
126         }
127         if (!(jfs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
128                 fprintf(stderr, _("%s is not a journal device.\n"),
129                         journal_path);
130                 goto no_valid_journal;
131         }
132
133         /* Get the journal superblock */
134         if ((retval = io_channel_read_blk(jfs->io, 1, -1024, buf))) {
135                 com_err(program_name, retval,
136                         _("while reading journal superblock"));
137                 goto no_valid_journal;
138         }
139
140         jsb = (journal_superblock_t *) buf;
141         if ((jsb->s_header.h_magic != (unsigned) ntohl(JFS_MAGIC_NUMBER)) ||
142             (jsb->s_header.h_blocktype != (unsigned) ntohl(JFS_SUPERBLOCK_V2))) {
143                 fprintf(stderr, _("Journal superblock not found!\n"));
144                 goto no_valid_journal;
145         }
146
147         /* Find the filesystem UUID */
148         nr_users = ntohl(jsb->s_nr_users);
149         for (i=0; i < nr_users; i++) {
150                 if (memcmp(fs->super->s_uuid,
151                            &jsb->s_users[i*16], 16) == 0)
152                         break;
153         }
154         if (i >= nr_users) {
155                 fprintf(stderr,
156                         _("Filesystem's UUID not found on journal device.\n"));
157                 commit_remove_journal = 1;
158                 goto no_valid_journal;
159         }
160         nr_users--;
161         for (i=0; i < nr_users; i++)
162                 memcpy(&jsb->s_users[i*16], &jsb->s_users[(i+1)*16], 16);
163         jsb->s_nr_users = htonl(nr_users);
164
165         /* Write back the journal superblock */
166         if ((retval = io_channel_write_blk(jfs->io, 1, -1024, buf))) {
167                 com_err(program_name, retval,
168                         "while writing journal superblock.");
169                 goto no_valid_journal;
170         }
171
172         commit_remove_journal = 1;
173
174 no_valid_journal:
175         if (commit_remove_journal == 0) {
176                 fprintf(stderr, _("Journal NOT removed\n"));
177                 exit(1);
178         }
179         fs->super->s_journal_dev = 0;
180         memset(fs->super->s_journal_uuid, 0,
181                sizeof(fs->super->s_journal_uuid));
182         ext2fs_mark_super_dirty(fs);
183         printf(_("Journal removed\n"));
184         free(journal_path);
185 }
186
187 /* Helper function for remove_journal_inode */
188 static int release_blocks_proc(ext2_filsys fs, blk_t *blocknr,
189                                int blockcnt, void *private)
190 {
191         blk_t   block;
192         int     group;
193
194         block = *blocknr;
195         ext2fs_unmark_block_bitmap(fs->block_map,block);
196         group = ext2fs_group_of_blk(fs, block);
197         fs->group_desc[group].bg_free_blocks_count++;
198         fs->super->s_free_blocks_count++;
199         return 0;
200 }
201
202 /*
203  * Remove the journal inode from the filesystem
204  */
205 static void remove_journal_inode(ext2_filsys fs)
206 {
207         struct ext2_inode       inode;
208         errcode_t               retval;
209         ino_t                   ino = fs->super->s_journal_inum;
210         
211         retval = ext2fs_read_inode(fs, ino,  &inode);
212         if (retval) {
213                 com_err(program_name, retval,
214                         _("while reading journal inode"));
215                 exit(1);
216         }
217         if (ino == EXT2_JOURNAL_INO) {
218                 retval = ext2fs_read_bitmaps(fs);
219                 if (retval) {
220                         com_err(program_name, retval,
221                                 _("while reading bitmaps"));
222                         exit(1);
223                 }
224                 retval = ext2fs_block_iterate(fs, ino, 0, NULL,
225                                               release_blocks_proc, NULL);
226                 if (retval) {
227                         com_err(program_name, retval,
228                                 _("while clearing journal inode"));
229                         exit(1);
230                 }
231                 memset(&inode, 0, sizeof(inode));
232                 ext2fs_mark_bb_dirty(fs);
233                 fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
234         } else
235                 inode.i_flags &= ~EXT2_IMMUTABLE_FL;
236         retval = ext2fs_write_inode(fs, ino, &inode);
237         if (retval) {
238                 com_err(program_name, retval,
239                         _("while writing journal inode"));
240                 exit(1);
241         }
242         fs->super->s_journal_inum = 0;
243         ext2fs_mark_super_dirty(fs);
244 }
245
246 /*
247  * Update the feature set as provided by the user.
248  */
249 static void update_feature_set(ext2_filsys fs, char *features)
250 {
251         int sparse, old_sparse, filetype, old_filetype;
252         int journal, old_journal;
253         struct ext2_super_block *sb= fs->super;
254
255         old_sparse = sb->s_feature_ro_compat &
256                 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
257         old_filetype = sb->s_feature_incompat &
258                 EXT2_FEATURE_INCOMPAT_FILETYPE;
259         old_journal = sb->s_feature_compat &
260                 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
261         if (e2p_edit_feature(features, &sb->s_feature_compat,
262                              ok_features)) {
263                 fprintf(stderr, _("Invalid filesystem option set: %s\n"),
264                         features);
265                 exit(1);
266         }
267         sparse = sb->s_feature_ro_compat &
268                 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
269         filetype = sb->s_feature_incompat &
270                 EXT2_FEATURE_INCOMPAT_FILETYPE;
271         journal = sb->s_feature_compat &
272                 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
273         if (old_journal && !journal) {
274                 if ((mount_flags & EXT2_MF_MOUNTED) &&
275                     !(mount_flags & EXT2_MF_READONLY)) {
276                         fprintf(stderr,
277                                 _("The has_journal flag may only be "
278                                   "cleared when the filesystem is\n"
279                                   "unmounted or mounted "
280                                   "read-only.\n"));
281                         exit(1);
282                 }
283                 if (sb->s_feature_incompat &
284                     EXT3_FEATURE_INCOMPAT_RECOVER) {
285                         fprintf(stderr,
286                                 _("The needs_recovery flag is set.  "
287                                   "Please run e2fsck before clearing\n"
288                                   "the has_journal flag.\n"));
289                         exit(1);
290                 }
291                 if (sb->s_journal_inum) {
292                         remove_journal_inode(fs);
293                 }
294                 if (sb->s_journal_dev) {
295                         remove_journal_device(fs);
296                 }
297         }
298         if (journal && !old_journal) {
299                 /*
300                  * If adding a journal flag, let the create journal
301                  * code below handle creating setting the flag and
302                  * creating the journal.  We supply a default size if
303                  * necessary.
304                  */
305                 if (!journal_size)
306                         journal_size = -1;
307                 sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
308         }
309
310         if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
311             (sb->s_feature_compat || sb->s_feature_ro_compat ||
312              sb->s_feature_incompat))
313                 ext2fs_update_dynamic_rev(fs);
314         if ((sparse != old_sparse) ||
315             (filetype != old_filetype)) {
316                 sb->s_state &= ~EXT2_VALID_FS;
317                 printf("\n%s\n", _(please_fsck));
318         }
319         ext2fs_mark_super_dirty(fs);
320 }
321
322 /*
323  * Add a journal to the filesystem.
324  */
325 static void add_journal(ext2_filsys fs)
326 {
327         unsigned long journal_blocks;
328         errcode_t       retval;
329         ext2_filsys     jfs;
330
331         if (fs->super->s_feature_compat &
332             EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
333                 fprintf(stderr, _("The filesystem already has a journal.\n"));
334                 goto err;
335         }
336         if (journal_device) {
337                 check_plausibility(journal_device);
338                 check_mount(journal_device, 0, _("journal"));
339                 retval = ext2fs_open(journal_device, EXT2_FLAG_RW|
340                                      EXT2_FLAG_JOURNAL_DEV_OK, 0,
341                                      fs->blocksize, unix_io_manager, &jfs);
342                 if (retval) {
343                         com_err(program_name, retval,
344                                 _("\n\twhile trying to open journal on %s\n"),
345                                 journal_device);
346                         goto err;
347                 }
348                 printf(_("Creating journal on device %s: "),
349                        journal_device);
350                 fflush(stdout);
351
352                 retval = ext2fs_add_journal_device(fs, jfs);
353                 ext2fs_close(jfs);
354                 if (retval) {
355                         com_err (program_name, retval,
356                                  _("while adding filesystem to journal on %s"),
357                                  journal_device);
358                         goto err;
359                 }
360                 printf(_("done\n"));
361         } else if (journal_size) {
362                 printf(_("Creating journal inode: "));
363                 fflush(stdout);
364                 journal_blocks = figure_journal_size(journal_size, fs);
365
366                 retval = ext2fs_add_journal_inode(fs, journal_blocks,
367                                                   journal_flags);
368                 if (retval) {
369                         fprintf(stderr, "\n");
370                         com_err(program_name, retval,
371                                 _("\n\twhile trying to create journal file"));
372                         exit(1);
373                 } else
374                         printf(_("done\n"));
375                 /*
376                  * If the filesystem wasn't mounted, we need to force
377                  * the block group descriptors out.
378                  */
379                 if ((mount_flags & EXT2_MF_MOUNTED) == 0)
380                         fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
381         }
382         print_check_message(fs);
383         return;
384
385 err:
386         if (journal_device)
387                 free(journal_device);
388         exit(1);
389 }
390
391 /*
392  * Given argv[0], return the program name.
393  */
394 static char *get_progname(char *argv_zero)
395 {
396         char    *cp;
397
398         cp = strrchr(argv_zero, '/');
399         if (!cp )
400                 return argv_zero;
401         else
402                 return cp+1;
403 }
404
405
406 static void parse_e2label_options(int argc, char ** argv)
407 {
408         if ((argc < 2) || (argc > 3)) {
409                 fprintf(stderr, _("Usage: e2label device [newlabel]\n"));
410                 exit(1);
411         }
412         device_name = argv[1];
413         if (argc == 3) {
414                 open_flag = EXT2_FLAG_RW | EXT2_FLAG_JOURNAL_DEV_OK;
415                 L_flag = 1;
416                 new_label = argv[2];
417         } else 
418                 print_label++;
419 }
420
421
422 static void parse_tune2fs_options(int argc, char **argv)
423 {
424         int c;
425         char * tmp;
426         struct group * gr;
427         struct passwd * pw;
428
429         printf("tune2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE);
430         while ((c = getopt (argc, argv, "c:e:fg:i:jlm:r:s:u:C:J:L:M:O:U:")) != EOF)
431                 switch (c)
432                 {
433                         case 'c':
434                                 max_mount_count = strtol (optarg, &tmp, 0);
435                                 if (*tmp || max_mount_count > 16000) {
436                                         com_err (program_name, 0,
437                                                  _("bad mounts count - %s"),
438                                                  optarg);
439                                         usage();
440                                 }
441                                 if (max_mount_count == 0)
442                                         max_mount_count = -1;
443                                 c_flag = 1;
444                                 open_flag = EXT2_FLAG_RW;
445                                 break;
446                         case 'C':
447                                 mount_count = strtoul (optarg, &tmp, 0);
448                                 if (*tmp || mount_count > 16000) {
449                                         com_err (program_name, 0,
450                                                  _("bad mounts count - %s"),
451                                                  optarg);
452                                         usage();
453                                 }
454                                 C_flag = 1;
455                                 open_flag = EXT2_FLAG_RW;
456                                 break;
457                         case 'e':
458                                 if (strcmp (optarg, "continue") == 0)
459                                         errors = EXT2_ERRORS_CONTINUE;
460                                 else if (strcmp (optarg, "remount-ro") == 0)
461                                         errors = EXT2_ERRORS_RO;
462                                 else if (strcmp (optarg, "panic") == 0)
463                                         errors = EXT2_ERRORS_PANIC;
464                                 else {
465                                         com_err (program_name, 0,
466                                                  _("bad error behavior - %s"),
467                                                  optarg);
468                                         usage();
469                                 }
470                                 e_flag = 1;
471                                 open_flag = EXT2_FLAG_RW;
472                                 break;
473                         case 'f': /* Force */
474                                 f_flag = 1;
475                                 break;
476                         case 'g':
477                                 resgid = strtoul (optarg, &tmp, 0);
478                                 if (*tmp) {
479                                         gr = getgrnam (optarg);
480                                         if (gr == NULL)
481                                                 tmp = optarg;
482                                         else {
483                                                 resgid = gr->gr_gid;
484                                                 *tmp =0;
485                                         }
486                                 }
487                                 if (*tmp) {
488                                         com_err (program_name, 0,
489                                                  _("bad gid/group name - %s"),
490                                                  optarg);
491                                         usage();
492                                 }
493                                 g_flag = 1;
494                                 open_flag = EXT2_FLAG_RW;
495                                 break;
496                         case 'i':
497                                 interval = strtoul (optarg, &tmp, 0);
498                                 switch (*tmp) {
499                                 case 's':
500                                         tmp++;
501                                         break;
502                                 case '\0':
503                                 case 'd':
504                                 case 'D': /* days */
505                                         interval *= 86400;
506                                         if (*tmp != '\0')
507                                                 tmp++;
508                                         break;
509                                 case 'm':
510                                 case 'M': /* months! */
511                                         interval *= 86400 * 30;
512                                         tmp++;
513                                         break;
514                                 case 'w':
515                                 case 'W': /* weeks */
516                                         interval *= 86400 * 7;
517                                         tmp++;
518                                         break;
519                                 }
520                                 if (*tmp || interval > (365 * 86400)) {
521                                         com_err (program_name, 0,
522                                                 _("bad interval - %s"), optarg);
523                                         usage();
524                                 }
525                                 i_flag = 1;
526                                 open_flag = EXT2_FLAG_RW;
527                                 break;
528                         case 'j':
529                                 if (!journal_size)
530                                         journal_size = -1;
531                                 open_flag = EXT2_FLAG_RW;
532                                 break;
533                         case 'J':
534                                 parse_journal_opts(optarg);
535                                 open_flag = EXT2_FLAG_RW;
536                                 break;
537                         case 'l':
538                                 l_flag = 1;
539                                 break;
540                         case 'L':
541                                 new_label = optarg;
542                                 L_flag = 1;
543                                 open_flag = EXT2_FLAG_RW |
544                                         EXT2_FLAG_JOURNAL_DEV_OK;
545                                 break;
546                         case 'm':
547                                 reserved_ratio = strtoul (optarg, &tmp, 0);
548                                 if (*tmp || reserved_ratio > 50) {
549                                         com_err (program_name, 0,
550                                                  _("bad reserved block ratio - %s"),
551                                                  optarg);
552                                         usage();
553                                 }
554                                 m_flag = 1;
555                                 open_flag = EXT2_FLAG_RW;
556                                 break;
557                         case 'M':
558                                 new_last_mounted = optarg;
559                                 M_flag = 1;
560                                 open_flag = EXT2_FLAG_RW;
561                                 break;
562                         case 'O':
563                                 if (features_cmd) {
564                                         com_err (program_name, 0,
565                                          _("-O may only be specified once"));
566                                         usage();
567                                 }
568                                 features_cmd = optarg;
569                                 open_flag = EXT2_FLAG_RW;
570                                 break;
571                         case 'r':
572                                 reserved_blocks = strtoul (optarg, &tmp, 0);
573                                 if (*tmp) {
574                                         com_err (program_name, 0,
575                                                  _("bad reserved blocks count - %s"),
576                                                  optarg);
577                                         usage();
578                                 }
579                                 r_flag = 1;
580                                 open_flag = EXT2_FLAG_RW;
581                                 break;
582                         case 's':
583                                 s_flag = atoi(optarg);
584                                 open_flag = EXT2_FLAG_RW;
585                                 break;
586                         case 'u':
587                                 resuid = strtoul (optarg, &tmp, 0);
588                                 if (*tmp) {
589                                         pw = getpwnam (optarg);
590                                         if (pw == NULL)
591                                                 tmp = optarg;
592                                         else {
593                                                 resuid = pw->pw_uid;
594                                                 *tmp = 0;
595                                         }
596                                 }
597                                 if (*tmp) {
598                                         com_err (program_name, 0,
599                                                  _("bad uid/user name - %s"),
600                                                  optarg);
601                                         usage();
602                                 }
603                                 u_flag = 1;
604                                 open_flag = EXT2_FLAG_RW;
605                                 break;
606                         case 'U':
607                                 new_UUID = optarg;
608                                 U_flag = 1;
609                                 open_flag = EXT2_FLAG_RW |
610                                         EXT2_FLAG_JOURNAL_DEV_OK;
611                                 break;
612                         default:
613                                 usage();
614                 }
615         if (optind < argc - 1 || optind == argc)
616                 usage();
617         if (!open_flag && !l_flag)
618                 usage();
619         device_name = argv[optind];
620 }       
621
622
623
624 int main (int argc, char ** argv)
625 {
626         errcode_t retval;
627         ext2_filsys fs;
628         struct ext2_super_block *sb;
629
630 #ifdef ENABLE_NLS
631         setlocale(LC_MESSAGES, "");
632         bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
633         textdomain(NLS_CAT_NAME);
634 #endif
635         if (argc && *argv)
636                 program_name = *argv;
637         initialize_ext2_error_table();
638
639         if (strcmp(get_progname(argv[0]), "e2label") == 0)
640                 parse_e2label_options(argc, argv);
641         else
642                 parse_tune2fs_options(argc, argv);
643         
644         retval = ext2fs_open (device_name, open_flag, 0, 0,
645                               unix_io_manager, &fs);
646         if (retval) {
647                 com_err (program_name, retval, _("while trying to open %s"),
648                          device_name);
649                 fprintf(stderr,
650                         _("Couldn't find valid filesystem superblock.\n"));
651                 exit(1);
652         }
653         sb = fs->super;
654         if (print_label) {
655                 /* For e2label emulation */
656                 printf("%.*s\n", (int) sizeof(sb->s_volume_name),
657                        sb->s_volume_name);
658                 exit(0);
659         }
660         retval = ext2fs_check_if_mounted(device_name, &mount_flags);
661         if (retval) {
662                 com_err("ext2fs_check_if_mount", retval,
663                         _("while determining whether %s is mounted."),
664                         device_name);
665                 exit(1);
666         }
667         /* Normally we only need to write out the superblock */
668         fs->flags |= EXT2_FLAG_SUPER_ONLY;
669
670         if (c_flag) {
671                 sb->s_max_mnt_count = max_mount_count;
672                 ext2fs_mark_super_dirty(fs);
673                 printf (_("Setting maximal mount count to %d\n"),
674                         max_mount_count);
675         }
676         if (C_flag) {
677                 sb->s_mnt_count = mount_count;
678                 ext2fs_mark_super_dirty(fs);
679                 printf (_("Setting current mount count to %d\n"), mount_count);
680         }
681         if (e_flag) {
682                 sb->s_errors = errors;
683                 ext2fs_mark_super_dirty(fs);
684                 printf (_("Setting error behavior to %d\n"), errors);
685         }
686         if (g_flag) {
687                 sb->s_def_resgid = resgid;
688                 ext2fs_mark_super_dirty(fs);
689                 printf (_("Setting reserved blocks gid to %lu\n"), resgid);
690         }
691         if (i_flag) {
692                 sb->s_checkinterval = interval;
693                 ext2fs_mark_super_dirty(fs);
694                 printf (_("Setting interval between check %lu seconds\n"), interval);
695         }
696         if (m_flag) {
697                 sb->s_r_blocks_count = (sb->s_blocks_count / 100)
698                         * reserved_ratio;
699                 ext2fs_mark_super_dirty(fs);
700                 printf (_("Setting reserved blocks percentage to %lu (%u blocks)\n"),
701                         reserved_ratio, sb->s_r_blocks_count);
702         }
703         if (r_flag) {
704                 if (reserved_blocks >= sb->s_blocks_count) {
705                         com_err (program_name, 0,
706                                  _("reserved blocks count is too big (%ul)"),
707                                  reserved_blocks);
708                         exit (1);
709                 }
710                 sb->s_r_blocks_count = reserved_blocks;
711                 ext2fs_mark_super_dirty(fs);
712                 printf (_("Setting reserved blocks count to %lu\n"),
713                         reserved_blocks);
714         }
715         if (s_flag == 1) {
716                 if (sb->s_feature_ro_compat &
717                     EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)
718                         fprintf(stderr, _("\nThe filesystem already"
719                                 " has sparse superblocks.\n"));
720                 else {
721                         sb->s_feature_ro_compat |=
722                                 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
723                         sb->s_state &= ~EXT2_VALID_FS;
724                         ext2fs_mark_super_dirty(fs);
725                         printf(_("\nSparse superblock flag set.  %s"),
726                                _(please_fsck));
727                 }
728         }
729         if (s_flag == 0) {
730                 if (!(sb->s_feature_ro_compat &
731                       EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))
732                         fprintf(stderr, _("\nThe filesystem already"
733                                 " has sparse superblocks disabled.\n"));
734                 else {
735                         sb->s_feature_ro_compat &=
736                                 ~EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
737                         sb->s_state &= ~EXT2_VALID_FS;
738                         fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
739                         ext2fs_mark_super_dirty(fs);
740                         printf(_("\nSparse superblock flag cleared.  %s"),
741                                _(please_fsck));
742                 }
743         }
744         if (u_flag) {
745                 sb->s_def_resuid = resuid;
746                 ext2fs_mark_super_dirty(fs);
747                 printf (_("Setting reserved blocks uid to %lu\n"), resuid);
748         }
749         if (L_flag) {
750                 if (strlen(new_label) > sizeof(sb->s_volume_name))
751                         fprintf(stderr, _("Warning: label too "
752                                 "long, truncating.\n"));
753                 memset(sb->s_volume_name, 0, sizeof(sb->s_volume_name));
754                 strncpy(sb->s_volume_name, new_label,
755                         sizeof(sb->s_volume_name));
756                 ext2fs_mark_super_dirty(fs);
757         }
758         if (M_flag) {
759                 memset(sb->s_last_mounted, 0, sizeof(sb->s_last_mounted));
760                 strncpy(sb->s_last_mounted, new_last_mounted,
761                         sizeof(sb->s_last_mounted));
762                 ext2fs_mark_super_dirty(fs);
763         }
764         if (features_cmd)
765                 update_feature_set(fs, features_cmd);
766         if (journal_size || journal_device)
767                 add_journal(fs);
768         
769         if (U_flag) {
770                 if ((strcasecmp(new_UUID, "null") == 0) ||
771                     (strcasecmp(new_UUID, "clear") == 0)) {
772                         uuid_clear(sb->s_uuid);
773                 } else if (strcasecmp(new_UUID, "time") == 0) {
774                         uuid_generate_time(sb->s_uuid);
775                 } else if (strcasecmp(new_UUID, "random") == 0) {
776                         uuid_generate(sb->s_uuid);
777                 } else if (uuid_parse(new_UUID, sb->s_uuid)) {
778                         com_err(program_name, 0, _("Invalid UUID format\n"));
779                         exit(1);
780                 }
781                 ext2fs_mark_super_dirty(fs);
782         }
783
784         if (l_flag)
785                 list_super (sb);
786         ext2fs_close (fs);
787         exit (0);
788 }