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