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