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