Whamcloud - gitweb
Remove dead code that wasn't in use from tune2fs.
[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_device;
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_device = get_spec_by_uuid(buf);
111
112         if (!journal_device) {
113                 journal_device =
114                         ext2fs_find_block_device(fs->super->s_journal_dev);
115                 if (!journal_device)
116                         return;
117         }
118
119         retval = ext2fs_open(journal_device, 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_device);
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_device);
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_inode       inode;
254         struct ext2_super_block *sb= fs->super;
255         errcode_t               retval;
256
257         old_sparse = sb->s_feature_ro_compat &
258                 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
259         old_filetype = sb->s_feature_incompat &
260                 EXT2_FEATURE_INCOMPAT_FILETYPE;
261         old_journal = sb->s_feature_compat &
262                 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
263         if (e2p_edit_feature(features, &sb->s_feature_compat,
264                              ok_features)) {
265                 fprintf(stderr, _("Invalid filesystem option set: %s\n"),
266                         features);
267                 exit(1);
268         }
269         sparse = sb->s_feature_ro_compat &
270                 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
271         filetype = sb->s_feature_incompat &
272                 EXT2_FEATURE_INCOMPAT_FILETYPE;
273         journal = sb->s_feature_compat &
274                 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
275         if (old_journal && !journal) {
276                 if ((mount_flags & EXT2_MF_MOUNTED) &&
277                     !(mount_flags & EXT2_MF_READONLY)) {
278                         fprintf(stderr,
279                                 _("The has_journal flag may only be "
280                                   "cleared when the filesystem is\n"
281                                   "unmounted or mounted "
282                                   "read-only.\n"));
283                         exit(1);
284                 }
285                 if (sb->s_feature_incompat &
286                     EXT3_FEATURE_INCOMPAT_RECOVER) {
287                         fprintf(stderr,
288                                 _("The needs_recovery flag is set.  "
289                                   "Please run e2fsck before clearing\n"
290                                   "the has_journal flag.\n"));
291                         exit(1);
292                 }
293                 if (sb->s_journal_inum) {
294                         remove_journal_inode(fs);
295                 }
296                 if (sb->s_journal_dev) {
297                         remove_journal_device(fs);
298                 }
299         }
300         if (journal && !old_journal) {
301                 /*
302                  * If adding a journal flag, let the create journal
303                  * code below handle creating setting the flag and
304                  * creating the journal.  We supply a default size if
305                  * necessary.
306                  */
307                 if (!journal_size)
308                         journal_size = -1;
309                 sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
310         }
311
312         if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
313             (sb->s_feature_compat || sb->s_feature_ro_compat ||
314              sb->s_feature_incompat))
315                 ext2fs_update_dynamic_rev(fs);
316         if ((sparse != old_sparse) ||
317             (filetype != old_filetype)) {
318                 sb->s_state &= ~EXT2_VALID_FS;
319                 printf("\n%s\n", _(please_fsck));
320         }
321         ext2fs_mark_super_dirty(fs);
322 }
323
324 /*
325  * Add a journal to the filesystem.
326  */
327 static void add_journal(ext2_filsys fs)
328 {
329         unsigned long journal_blocks;
330         errcode_t       retval;
331         ext2_filsys     jfs;
332
333         if (fs->super->s_feature_compat &
334             EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
335                 fprintf(stderr, _("The filesystem already has a journal.\n"));
336                 goto err;
337         }
338         if (journal_device) {
339                 check_plausibility(journal_device);
340                 check_mount(journal_device, 0, _("journal"));
341                 retval = ext2fs_open(journal_device, EXT2_FLAG_RW|
342                                      EXT2_FLAG_JOURNAL_DEV_OK, 0,
343                                      fs->blocksize, unix_io_manager, &jfs);
344                 if (retval) {
345                         com_err(program_name, retval,
346                                 _("\n\twhile trying to open journal on %s\n"),
347                                 journal_device);
348                         goto err;
349                 }
350                 printf(_("Creating journal on device %s: "),
351                        journal_device);
352                 fflush(stdout);
353
354                 retval = ext2fs_add_journal_device(fs, jfs);
355                 ext2fs_close(jfs);
356                 if (retval) {
357                         com_err (program_name, retval,
358                                  _("while adding filesystem to journal on %s"),
359                                  journal_device);
360                         goto err;
361                 }
362                 printf(_("done\n"));
363         } else if (journal_size) {
364                 printf(_("Creating journal inode: "));
365                 fflush(stdout);
366                 journal_blocks = figure_journal_size(journal_size, fs);
367
368                 retval = ext2fs_add_journal_inode(fs, journal_blocks,
369                                                   journal_flags);
370                 if (retval) {
371                         fprintf(stderr, "\n");
372                         com_err(program_name, retval,
373                                 _("\n\twhile trying to create journal file"));
374                         exit(1);
375                 } else
376                         printf(_("done\n"));
377                 /*
378                  * If the filesystem wasn't mounted, we need to force
379                  * the block group descriptors out.
380                  */
381                 if ((mount_flags & EXT2_MF_MOUNTED) == 0)
382                         fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
383         }
384         print_check_message(fs);
385         return;
386
387 err:
388         if (journal_device)
389                 free(journal_device);
390         exit(1);
391 }
392
393 /*
394  * Given argv[0], return the program name.
395  */
396 static char *get_progname(char *argv_zero)
397 {
398         char    *cp;
399
400         cp = strrchr(argv_zero, '/');
401         if (!cp )
402                 return argv_zero;
403         else
404                 return cp+1;
405 }
406
407
408 static void parse_e2label_options(int argc, char ** argv)
409 {
410         if ((argc < 2) || (argc > 3)) {
411                 fprintf(stderr, _("Usage: e2label device [newlabel]\n"));
412                 exit(1);
413         }
414         device_name = argv[1];
415         if (argc == 3) {
416                 open_flag = EXT2_FLAG_RW | EXT2_FLAG_JOURNAL_DEV_OK;
417                 L_flag = 1;
418                 new_label = argv[2];
419         } else 
420                 print_label++;
421 }
422
423
424 static void parse_tune2fs_options(int argc, char **argv)
425 {
426         int c;
427         char * tmp;
428         struct group * gr;
429         struct passwd * pw;
430
431         printf("tune2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE);
432         while ((c = getopt (argc, argv, "c:e:fg:i:jlm:r:s:u:C:J:L:M:O:U:")) != EOF)
433                 switch (c)
434                 {
435                         case 'c':
436                                 max_mount_count = strtol (optarg, &tmp, 0);
437                                 if (*tmp || max_mount_count > 16000) {
438                                         com_err (program_name, 0,
439                                                  _("bad mounts count - %s"),
440                                                  optarg);
441                                         usage();
442                                 }
443                                 if (max_mount_count == 0)
444                                         max_mount_count = -1;
445                                 c_flag = 1;
446                                 open_flag = EXT2_FLAG_RW;
447                                 break;
448                         case 'C':
449                                 mount_count = strtoul (optarg, &tmp, 0);
450                                 if (*tmp || mount_count > 16000) {
451                                         com_err (program_name, 0,
452                                                  _("bad mounts count - %s"),
453                                                  optarg);
454                                         usage();
455                                 }
456                                 C_flag = 1;
457                                 open_flag = EXT2_FLAG_RW;
458                                 break;
459                         case 'e':
460                                 if (strcmp (optarg, "continue") == 0)
461                                         errors = EXT2_ERRORS_CONTINUE;
462                                 else if (strcmp (optarg, "remount-ro") == 0)
463                                         errors = EXT2_ERRORS_RO;
464                                 else if (strcmp (optarg, "panic") == 0)
465                                         errors = EXT2_ERRORS_PANIC;
466                                 else {
467                                         com_err (program_name, 0,
468                                                  _("bad error behavior - %s"),
469                                                  optarg);
470                                         usage();
471                                 }
472                                 e_flag = 1;
473                                 open_flag = EXT2_FLAG_RW;
474                                 break;
475                         case 'f': /* Force */
476                                 f_flag = 1;
477                                 break;
478                         case 'g':
479                                 resgid = strtoul (optarg, &tmp, 0);
480                                 if (*tmp) {
481                                         gr = getgrnam (optarg);
482                                         if (gr == NULL)
483                                                 tmp = optarg;
484                                         else {
485                                                 resgid = gr->gr_gid;
486                                                 *tmp =0;
487                                         }
488                                 }
489                                 if (*tmp) {
490                                         com_err (program_name, 0,
491                                                  _("bad gid/group name - %s"),
492                                                  optarg);
493                                         usage();
494                                 }
495                                 g_flag = 1;
496                                 open_flag = EXT2_FLAG_RW;
497                                 break;
498                         case 'i':
499                                 interval = strtoul (optarg, &tmp, 0);
500                                 switch (*tmp) {
501                                 case 's':
502                                         tmp++;
503                                         break;
504                                 case '\0':
505                                 case 'd':
506                                 case 'D': /* days */
507                                         interval *= 86400;
508                                         if (*tmp != '\0')
509                                                 tmp++;
510                                         break;
511                                 case 'm':
512                                 case 'M': /* months! */
513                                         interval *= 86400 * 30;
514                                         tmp++;
515                                         break;
516                                 case 'w':
517                                 case 'W': /* weeks */
518                                         interval *= 86400 * 7;
519                                         tmp++;
520                                         break;
521                                 }
522                                 if (*tmp || interval > (365 * 86400)) {
523                                         com_err (program_name, 0,
524                                                 _("bad interval - %s"), optarg);
525                                         usage();
526                                 }
527                                 i_flag = 1;
528                                 open_flag = EXT2_FLAG_RW;
529                                 break;
530                         case 'j':
531                                 if (!journal_size)
532                                         journal_size = -1;
533                                 open_flag = EXT2_FLAG_RW;
534                                 break;
535                         case 'J':
536                                 parse_journal_opts(optarg);
537                                 open_flag = EXT2_FLAG_RW;
538                                 break;
539                         case 'l':
540                                 l_flag = 1;
541                                 break;
542                         case 'L':
543                                 new_label = optarg;
544                                 L_flag = 1;
545                                 open_flag = EXT2_FLAG_RW |
546                                         EXT2_FLAG_JOURNAL_DEV_OK;
547                                 break;
548                         case 'm':
549                                 reserved_ratio = strtoul (optarg, &tmp, 0);
550                                 if (*tmp || reserved_ratio > 50) {
551                                         com_err (program_name, 0,
552                                                  _("bad reserved block ratio - %s"),
553                                                  optarg);
554                                         usage();
555                                 }
556                                 m_flag = 1;
557                                 open_flag = EXT2_FLAG_RW;
558                                 break;
559                         case 'M':
560                                 new_last_mounted = optarg;
561                                 M_flag = 1;
562                                 open_flag = EXT2_FLAG_RW;
563                                 break;
564                         case 'O':
565                                 if (features_cmd) {
566                                         com_err (program_name, 0,
567                                          _("-O may only be specified once"));
568                                         usage();
569                                 }
570                                 features_cmd = optarg;
571                                 open_flag = EXT2_FLAG_RW;
572                                 break;
573                         case 'r':
574                                 reserved_blocks = strtoul (optarg, &tmp, 0);
575                                 if (*tmp) {
576                                         com_err (program_name, 0,
577                                                  _("bad reserved blocks count - %s"),
578                                                  optarg);
579                                         usage();
580                                 }
581                                 r_flag = 1;
582                                 open_flag = EXT2_FLAG_RW;
583                                 break;
584                         case 's':
585                                 s_flag = atoi(optarg);
586                                 open_flag = EXT2_FLAG_RW;
587                                 break;
588                         case 'u':
589                                 resuid = strtoul (optarg, &tmp, 0);
590                                 if (*tmp) {
591                                         pw = getpwnam (optarg);
592                                         if (pw == NULL)
593                                                 tmp = optarg;
594                                         else {
595                                                 resuid = pw->pw_uid;
596                                                 *tmp = 0;
597                                         }
598                                 }
599                                 if (*tmp) {
600                                         com_err (program_name, 0,
601                                                  _("bad uid/user name - %s"),
602                                                  optarg);
603                                         usage();
604                                 }
605                                 u_flag = 1;
606                                 open_flag = EXT2_FLAG_RW;
607                                 break;
608                         case 'U':
609                                 new_UUID = optarg;
610                                 U_flag = 1;
611                                 open_flag = EXT2_FLAG_RW |
612                                         EXT2_FLAG_JOURNAL_DEV_OK;
613                                 break;
614                         default:
615                                 usage();
616                 }
617         if (optind < argc - 1 || optind == argc)
618                 usage();
619         if (!open_flag && !l_flag)
620                 usage();
621         device_name = argv[optind];
622 }       
623
624
625
626 int main (int argc, char ** argv)
627 {
628         errcode_t retval;
629         ext2_filsys fs;
630         struct ext2_super_block *sb;
631
632 #ifdef ENABLE_NLS
633         setlocale(LC_MESSAGES, "");
634         bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
635         textdomain(NLS_CAT_NAME);
636 #endif
637         if (argc && *argv)
638                 program_name = *argv;
639         initialize_ext2_error_table();
640
641         if (strcmp(get_progname(argv[0]), "e2label") == 0)
642                 parse_e2label_options(argc, argv);
643         else
644                 parse_tune2fs_options(argc, argv);
645         
646         retval = ext2fs_open (device_name, open_flag, 0, 0,
647                               unix_io_manager, &fs);
648         if (retval) {
649                 com_err (program_name, retval, _("while trying to open %s"),
650                          device_name);
651                 fprintf(stderr,
652                         _("Couldn't find valid filesystem superblock.\n"));
653                 exit(1);
654         }
655         sb = fs->super;
656         if (print_label) {
657                 /* For e2label emulation */
658                 printf("%.*s\n", (int) sizeof(sb->s_volume_name),
659                        sb->s_volume_name);
660                 exit(0);
661         }
662         retval = ext2fs_check_if_mounted(device_name, &mount_flags);
663         if (retval) {
664                 com_err("ext2fs_check_if_mount", retval,
665                         _("while determining whether %s is mounted."),
666                         device_name);
667                 exit(1);
668         }
669         /* Normally we only need to write out the superblock */
670         fs->flags |= EXT2_FLAG_SUPER_ONLY;
671
672         if (c_flag) {
673                 sb->s_max_mnt_count = max_mount_count;
674                 ext2fs_mark_super_dirty(fs);
675                 printf (_("Setting maximal mount count to %d\n"),
676                         max_mount_count);
677         }
678         if (C_flag) {
679                 sb->s_mnt_count = mount_count;
680                 ext2fs_mark_super_dirty(fs);
681                 printf (_("Setting current mount count to %d\n"), mount_count);
682         }
683         if (e_flag) {
684                 sb->s_errors = errors;
685                 ext2fs_mark_super_dirty(fs);
686                 printf (_("Setting error behavior to %d\n"), errors);
687         }
688         if (g_flag) {
689                 sb->s_def_resgid = resgid;
690                 ext2fs_mark_super_dirty(fs);
691                 printf (_("Setting reserved blocks gid to %lu\n"), resgid);
692         }
693         if (i_flag) {
694                 sb->s_checkinterval = interval;
695                 ext2fs_mark_super_dirty(fs);
696                 printf (_("Setting interval between check %lu seconds\n"), interval);
697         }
698         if (m_flag) {
699                 sb->s_r_blocks_count = (sb->s_blocks_count / 100)
700                         * reserved_ratio;
701                 ext2fs_mark_super_dirty(fs);
702                 printf (_("Setting reserved blocks percentage to %lu (%u blocks)\n"),
703                         reserved_ratio, sb->s_r_blocks_count);
704         }
705         if (r_flag) {
706                 if (reserved_blocks >= sb->s_blocks_count) {
707                         com_err (program_name, 0,
708                                  _("reserved blocks count is too big (%ul)"),
709                                  reserved_blocks);
710                         exit (1);
711                 }
712                 sb->s_r_blocks_count = reserved_blocks;
713                 ext2fs_mark_super_dirty(fs);
714                 printf (_("Setting reserved blocks count to %lu\n"),
715                         reserved_blocks);
716         }
717         if (s_flag == 1) {
718                 if (sb->s_feature_ro_compat &
719                     EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)
720                         fprintf(stderr, _("\nThe filesystem already"
721                                 " has sparse superblocks.\n"));
722                 else {
723                         sb->s_feature_ro_compat |=
724                                 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
725                         sb->s_state &= ~EXT2_VALID_FS;
726                         ext2fs_mark_super_dirty(fs);
727                         printf(_("\nSparse superblock flag set.  %s"),
728                                _(please_fsck));
729                 }
730         }
731         if (s_flag == 0) {
732                 if (!(sb->s_feature_ro_compat &
733                       EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))
734                         fprintf(stderr, _("\nThe filesystem already"
735                                 " has sparse superblocks disabled.\n"));
736                 else {
737                         sb->s_feature_ro_compat &=
738                                 ~EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
739                         sb->s_state &= ~EXT2_VALID_FS;
740                         fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
741                         ext2fs_mark_super_dirty(fs);
742                         printf(_("\nSparse superblock flag cleared.  %s"),
743                                _(please_fsck));
744                 }
745         }
746         if (u_flag) {
747                 sb->s_def_resuid = resuid;
748                 ext2fs_mark_super_dirty(fs);
749                 printf (_("Setting reserved blocks uid to %lu\n"), resuid);
750         }
751         if (L_flag) {
752                 if (strlen(new_label) > sizeof(sb->s_volume_name))
753                         fprintf(stderr, _("Warning: label too "
754                                 "long, truncating.\n"));
755                 memset(sb->s_volume_name, 0, sizeof(sb->s_volume_name));
756                 strncpy(sb->s_volume_name, new_label,
757                         sizeof(sb->s_volume_name));
758                 ext2fs_mark_super_dirty(fs);
759         }
760         if (M_flag) {
761                 memset(sb->s_last_mounted, 0, sizeof(sb->s_last_mounted));
762                 strncpy(sb->s_last_mounted, new_last_mounted,
763                         sizeof(sb->s_last_mounted));
764                 ext2fs_mark_super_dirty(fs);
765         }
766         if (features_cmd)
767                 update_feature_set(fs, features_cmd);
768         if (journal_size || journal_device)
769                 add_journal(fs);
770         
771         if (U_flag) {
772                 if ((strcasecmp(new_UUID, "null") == 0) ||
773                     (strcasecmp(new_UUID, "clear") == 0)) {
774                         uuid_clear(sb->s_uuid);
775                 } else if (strcasecmp(new_UUID, "time") == 0) {
776                         uuid_generate_time(sb->s_uuid);
777                 } else if (strcasecmp(new_UUID, "random") == 0) {
778                         uuid_generate(sb->s_uuid);
779                 } else if (uuid_parse(new_UUID, sb->s_uuid)) {
780                         com_err(program_name, 0, _("Invalid UUID format\n"));
781                         exit(1);
782                 }
783                 ext2fs_mark_super_dirty(fs);
784         }
785
786         if (l_flag)
787                 list_super (sb);
788         ext2fs_close (fs);
789         exit (0);
790 }