busybox/e2fsprogs/old_e2fsprogs/tune2fs.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * tune2fs.c - Change the file system parameters on an ext2 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, 1998, 1999, 2000 by Theodore Ts'o.
  10 *
  11 * Licensed under GPLv2, see file LICENSE in this tarball for details.
  12 */
  13
  14/*
  15 * History:
  16 * 93/06/01     - Creation
  17 * 93/10/31     - Added the -c option to change the maximal mount counts
  18 * 93/12/14     - Added -l flag to list contents of superblock
  19 *                M.J.E. Mol (marcel@duteca.et.tudelft.nl)
  20 *                F.W. ten Wolde (franky@duteca.et.tudelft.nl)
  21 * 93/12/29     - Added the -e option to change errors behavior
  22 * 94/02/27     - Ported to use the ext2fs library
  23 * 94/03/06     - Added the checks interval from Uwe Ohse (uwe@tirka.gun.de)
  24 */
  25
  26#include <sys/types.h>
  27#include <fcntl.h>
  28#include <stdio.h>
  29#include <stdlib.h>
  30#include <string.h>
  31#include <time.h>
  32#include <unistd.h>
  33#include <getopt.h>
  34
  35#include "e2fsbb.h"
  36#include "ext2fs/ext2_fs.h"
  37#include "ext2fs/ext2fs.h"
  38#include "uuid/uuid.h"
  39#include "e2p/e2p.h"
  40#include "ext2fs/kernel-jbd.h"
  41#include "util.h"
  42#include "blkid/blkid.h"
  43
  44#include "libbb.h"
  45
  46static char * device_name = NULL;
  47static char * new_label, *new_last_mounted, *new_UUID;
  48static char * io_options;
  49static int c_flag, C_flag, e_flag, f_flag, g_flag, i_flag, l_flag, L_flag;
  50static int m_flag, M_flag, r_flag, s_flag = -1, u_flag, U_flag, T_flag;
  51static time_t last_check_time;
  52static int print_label;
  53static int max_mount_count, mount_count, mount_flags;
  54static unsigned long interval, reserved_blocks;
  55static unsigned reserved_ratio;
  56static unsigned long resgid, resuid;
  57static unsigned short errors;
  58static int open_flag;
  59static char *features_cmd;
  60static char *mntopts_cmd;
  61
  62static int journal_size, journal_flags;
  63static char *journal_device = NULL;
  64
  65static const char *please_fsck = "Please run e2fsck on the filesystem\n";
  66
  67static __u32 ok_features[3] = {
  68        EXT3_FEATURE_COMPAT_HAS_JOURNAL | EXT2_FEATURE_COMPAT_DIR_INDEX,
  69        EXT2_FEATURE_INCOMPAT_FILETYPE,
  70        EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
  71};
  72
  73/*
  74 * Remove an external journal from the filesystem
  75 */
  76static void remove_journal_device(ext2_filsys fs)
  77{
  78        char            *journal_path;
  79        ext2_filsys     jfs;
  80        char            buf[1024];
  81        journal_superblock_t    *jsb;
  82        int             i, nr_users;
  83        errcode_t       retval;
  84        int             commit_remove_journal = 0;
  85        io_manager      io_ptr;
  86
  87        if (f_flag)
  88                commit_remove_journal = 1; /* force removal even if error */
  89
  90        uuid_unparse(fs->super->s_journal_uuid, buf);
  91        journal_path = blkid_get_devname(NULL, "UUID", buf);
  92
  93        if (!journal_path) {
  94                journal_path =
  95                        ext2fs_find_block_device(fs->super->s_journal_dev);
  96                if (!journal_path)
  97                        return;
  98        }
  99
 100        io_ptr = unix_io_manager;
 101        retval = ext2fs_open(journal_path, EXT2_FLAG_RW|
 102                             EXT2_FLAG_JOURNAL_DEV_OK, 0,
 103                             fs->blocksize, io_ptr, &jfs);
 104        if (retval) {
 105                bb_error_msg("Failed to open external journal");
 106                goto no_valid_journal;
 107        }
 108        if (!(jfs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
 109                bb_error_msg("%s is not a journal device", journal_path);
 110                goto no_valid_journal;
 111        }
 112
 113        /* Get the journal superblock */
 114        if ((retval = io_channel_read_blk(jfs->io, 1, -1024, buf))) {
 115                bb_error_msg("Failed to read journal superblock");
 116                goto no_valid_journal;
 117        }
 118
 119        jsb = (journal_superblock_t *) buf;
 120        if ((jsb->s_header.h_magic != (unsigned) ntohl(JFS_MAGIC_NUMBER)) ||
 121            (jsb->s_header.h_blocktype != (unsigned) ntohl(JFS_SUPERBLOCK_V2))) {
 122                bb_error_msg("Journal superblock not found!");
 123                goto no_valid_journal;
 124        }
 125
 126        /* Find the filesystem UUID */
 127        nr_users = ntohl(jsb->s_nr_users);
 128        for (i=0; i < nr_users; i++) {
 129                if (memcmp(fs->super->s_uuid,
 130                           &jsb->s_users[i*16], 16) == 0)
 131                        break;
 132        }
 133        if (i >= nr_users) {
 134                bb_error_msg("Filesystem's UUID not found on journal device");
 135                commit_remove_journal = 1;
 136                goto no_valid_journal;
 137        }
 138        nr_users--;
 139        for (i=0; i < nr_users; i++)
 140                memcpy(&jsb->s_users[i*16], &jsb->s_users[(i+1)*16], 16);
 141        jsb->s_nr_users = htonl(nr_users);
 142
 143        /* Write back the journal superblock */
 144        if ((retval = io_channel_write_blk(jfs->io, 1, -1024, buf))) {
 145                bb_error_msg("Failed to write journal superblock");
 146                goto no_valid_journal;
 147        }
 148
 149        commit_remove_journal = 1;
 150
 151no_valid_journal:
 152        if (commit_remove_journal == 0)
 153                bb_error_msg_and_die("Journal NOT removed");
 154        fs->super->s_journal_dev = 0;
 155        uuid_clear(fs->super->s_journal_uuid);
 156        ext2fs_mark_super_dirty(fs);
 157        puts("Journal removed");
 158        free(journal_path);
 159}
 160
 161/* Helper function for remove_journal_inode */
 162static int release_blocks_proc(ext2_filsys fs, blk_t *blocknr,
 163                               int blockcnt EXT2FS_ATTR((unused)),
 164                               void *private EXT2FS_ATTR((unused)))
 165{
 166        blk_t   block;
 167        int     group;
 168
 169        block = *blocknr;
 170        ext2fs_unmark_block_bitmap(fs->block_map,block);
 171        group = ext2fs_group_of_blk(fs, block);
 172        fs->group_desc[group].bg_free_blocks_count++;
 173        fs->super->s_free_blocks_count++;
 174        return 0;
 175}
 176
 177/*
 178 * Remove the journal inode from the filesystem
 179 */
 180static void remove_journal_inode(ext2_filsys fs)
 181{
 182        struct ext2_inode       inode;
 183        errcode_t               retval;
 184        ino_t                   ino = fs->super->s_journal_inum;
 185        char *msg = "to read";
 186        char *s = "journal inode";
 187
 188        retval = ext2fs_read_inode(fs, ino,  &inode);
 189        if (retval)
 190                goto REMOVE_JOURNAL_INODE_ERROR;
 191        if (ino == EXT2_JOURNAL_INO) {
 192                retval = ext2fs_read_bitmaps(fs);
 193                if (retval) {
 194                        msg = "to read bitmaps";
 195                        s = "";
 196                        goto REMOVE_JOURNAL_INODE_ERROR;
 197                }
 198                retval = ext2fs_block_iterate(fs, ino, 0, NULL,
 199                                              release_blocks_proc, NULL);
 200                if (retval) {
 201                        msg = "clearing";
 202                        goto REMOVE_JOURNAL_INODE_ERROR;
 203                }
 204                memset(&inode, 0, sizeof(inode));
 205                ext2fs_mark_bb_dirty(fs);
 206                fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
 207        } else
 208                inode.i_flags &= ~EXT2_IMMUTABLE_FL;
 209        retval = ext2fs_write_inode(fs, ino, &inode);
 210        if (retval) {
 211                msg = "writing";
 212REMOVE_JOURNAL_INODE_ERROR:
 213                bb_error_msg_and_die("Failed %s %s", msg, s);
 214        }
 215        fs->super->s_journal_inum = 0;
 216        ext2fs_mark_super_dirty(fs);
 217}
 218
 219/*
 220 * Update the default mount options
 221 */
 222static void update_mntopts(ext2_filsys fs, char *mntopts)
 223{
 224        struct ext2_super_block *sb= fs->super;
 225
 226        if (e2p_edit_mntopts(mntopts, &sb->s_default_mount_opts, ~0))
 227                bb_error_msg_and_die("Invalid mount option set: %s", mntopts);
 228        ext2fs_mark_super_dirty(fs);
 229}
 230
 231/*
 232 * Update the feature set as provided by the user.
 233 */
 234static void update_feature_set(ext2_filsys fs, char *features)
 235{
 236        int sparse, old_sparse, filetype, old_filetype;
 237        int journal, old_journal, dxdir, old_dxdir;
 238        struct ext2_super_block *sb= fs->super;
 239        __u32   old_compat, old_incompat, old_ro_compat;
 240
 241        old_compat = sb->s_feature_compat;
 242        old_ro_compat = sb->s_feature_ro_compat;
 243        old_incompat = sb->s_feature_incompat;
 244
 245        old_sparse = sb->s_feature_ro_compat &
 246                EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
 247        old_filetype = sb->s_feature_incompat &
 248                EXT2_FEATURE_INCOMPAT_FILETYPE;
 249        old_journal = sb->s_feature_compat &
 250                EXT3_FEATURE_COMPAT_HAS_JOURNAL;
 251        old_dxdir = sb->s_feature_compat &
 252                EXT2_FEATURE_COMPAT_DIR_INDEX;
 253        if (e2p_edit_feature(features, &sb->s_feature_compat, ok_features))
 254                bb_error_msg_and_die("Invalid filesystem option set: %s", features);
 255        sparse = sb->s_feature_ro_compat &
 256                EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
 257        filetype = sb->s_feature_incompat &
 258                EXT2_FEATURE_INCOMPAT_FILETYPE;
 259        journal = sb->s_feature_compat &
 260                EXT3_FEATURE_COMPAT_HAS_JOURNAL;
 261        dxdir = sb->s_feature_compat &
 262                EXT2_FEATURE_COMPAT_DIR_INDEX;
 263        if (old_journal && !journal) {
 264                if ((mount_flags & EXT2_MF_MOUNTED) &&
 265                    !(mount_flags & EXT2_MF_READONLY)) {
 266                        bb_error_msg_and_die(
 267                                "The has_journal flag may only be "
 268                                "cleared when the filesystem is\n"
 269                                "unmounted or mounted "
 270                                "read-only");
 271                }
 272                if (sb->s_feature_incompat &
 273                    EXT3_FEATURE_INCOMPAT_RECOVER) {
 274                        bb_error_msg_and_die(
 275                                "The needs_recovery flag is set.  "
 276                                "%s before clearing the has_journal flag.",
 277                                please_fsck);
 278                }
 279                if (sb->s_journal_inum) {
 280                        remove_journal_inode(fs);
 281                }
 282                if (sb->s_journal_dev) {
 283                        remove_journal_device(fs);
 284                }
 285        }
 286        if (journal && !old_journal) {
 287                /*
 288                 * If adding a journal flag, let the create journal
 289                 * code below handle creating setting the flag and
 290                 * creating the journal.  We supply a default size if
 291                 * necessary.
 292                 */
 293                if (!journal_size)
 294                        journal_size = -1;
 295                sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
 296        }
 297        if (dxdir && !old_dxdir) {
 298                if (!sb->s_def_hash_version)
 299                        sb->s_def_hash_version = EXT2_HASH_TEA;
 300                if (uuid_is_null((unsigned char *) sb->s_hash_seed))
 301                        uuid_generate((unsigned char *) sb->s_hash_seed);
 302        }
 303
 304        if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
 305            (sb->s_feature_compat || sb->s_feature_ro_compat ||
 306             sb->s_feature_incompat))
 307                ext2fs_update_dynamic_rev(fs);
 308        if ((sparse != old_sparse) ||
 309            (filetype != old_filetype)) {
 310                sb->s_state &= ~EXT2_VALID_FS;
 311                printf("\n%s\n", please_fsck);
 312        }
 313        if ((old_compat != sb->s_feature_compat) ||
 314            (old_ro_compat != sb->s_feature_ro_compat) ||
 315            (old_incompat != sb->s_feature_incompat))
 316                ext2fs_mark_super_dirty(fs);
 317}
 318
 319/*
 320 * Add a journal to the filesystem.
 321 */
 322static void add_journal(ext2_filsys fs)
 323{
 324        if (fs->super->s_feature_compat &
 325            EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
 326                bb_error_msg_and_die("The filesystem already has a journal");
 327        }
 328        if (journal_device) {
 329                make_journal_device(journal_device, fs, 0, 0);
 330        } else if (journal_size) {
 331                make_journal_blocks(fs, journal_size, journal_flags, 0);
 332                /*
 333                 * If the filesystem wasn't mounted, we need to force
 334                 * the block group descriptors out.
 335                 */
 336                if ((mount_flags & EXT2_MF_MOUNTED) == 0)
 337                        fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
 338        }
 339        print_check_message(fs);
 340}
 341
 342/*
 343 * Busybox stuff
 344 */
 345static char * x_blkid_get_devname(const char *token)
 346{
 347        char * dev_name;
 348
 349        if (!(dev_name = blkid_get_devname(NULL, token, NULL)))
 350                bb_error_msg_and_die("Unable to resolve '%s'", token);
 351        return dev_name;
 352}
 353
 354#ifdef CONFIG_E2LABEL
 355static void parse_e2label_options(int argc, char ** argv)
 356{
 357        if ((argc < 2) || (argc > 3))
 358                bb_show_usage();
 359        io_options = strchr(argv[1], '?');
 360        if (io_options)
 361                *io_options++ = 0;
 362        device_name = x_blkid_get_devname(argv[1]);
 363        if (argc == 3) {
 364                open_flag = EXT2_FLAG_RW | EXT2_FLAG_JOURNAL_DEV_OK;
 365                L_flag = 1;
 366                new_label = argv[2];
 367        } else
 368                print_label++;
 369}
 370#else
 371#define parse_e2label_options(x,y)
 372#endif
 373
 374static time_t parse_time(char *str)
 375{
 376        struct  tm      ts;
 377
 378        if (strcmp(str, "now") == 0) {
 379                return time(0);
 380        }
 381        memset(&ts, 0, sizeof(ts));
 382#ifdef HAVE_STRPTIME
 383        strptime(str, "%Y%m%d%H%M%S", &ts);
 384#else
 385        sscanf(str, "%4d%2d%2d%2d%2d%2d", &ts.tm_year, &ts.tm_mon,
 386               &ts.tm_mday, &ts.tm_hour, &ts.tm_min, &ts.tm_sec);
 387        ts.tm_year -= 1900;
 388        ts.tm_mon -= 1;
 389        if (ts.tm_year < 0 || ts.tm_mon < 0 || ts.tm_mon > 11 ||
 390            ts.tm_mday < 0 || ts.tm_mday > 31 || ts.tm_hour > 23 ||
 391            ts.tm_min > 59 || ts.tm_sec > 61)
 392                ts.tm_mday = 0;
 393#endif
 394        if (ts.tm_mday == 0) {
 395                bb_error_msg_and_die("Cannot parse date/time specifier: %s", str);
 396        }
 397        return mktime(&ts);
 398}
 399
 400static void parse_tune2fs_options(int argc, char **argv)
 401{
 402        int c;
 403        char * tmp;
 404
 405        printf("tune2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE);
 406        while ((c = getopt(argc, argv, "c:e:fg:i:jlm:o:r:s:u:C:J:L:M:O:T:U:")) != EOF)
 407                switch (c)
 408                {
 409                        case 'c':
 410                                max_mount_count = xatou_range(optarg, 0, 16000);
 411                                if (max_mount_count == 0)
 412                                        max_mount_count = -1;
 413                                c_flag = 1;
 414                                open_flag = EXT2_FLAG_RW;
 415                                break;
 416                        case 'C':
 417                                mount_count = xatou_range(optarg, 0, 16000);
 418                                C_flag = 1;
 419                                open_flag = EXT2_FLAG_RW;
 420                                break;
 421                        case 'e':
 422                                if (strcmp (optarg, "continue") == 0)
 423                                        errors = EXT2_ERRORS_CONTINUE;
 424                                else if (strcmp (optarg, "remount-ro") == 0)
 425                                        errors = EXT2_ERRORS_RO;
 426                                else if (strcmp (optarg, "panic") == 0)
 427                                        errors = EXT2_ERRORS_PANIC;
 428                                else {
 429                                        bb_error_msg_and_die("bad error behavior - %s", optarg);
 430                                }
 431                                e_flag = 1;
 432                                open_flag = EXT2_FLAG_RW;
 433                                break;
 434                        case 'f': /* Force */
 435                                f_flag = 1;
 436                                break;
 437                        case 'g':
 438                                resgid = bb_strtoul(optarg, NULL, 10);
 439                                if (errno)
 440                                        resgid = xgroup2gid(optarg);
 441                                g_flag = 1;
 442                                open_flag = EXT2_FLAG_RW;
 443                                break;
 444                        case 'i':
 445                                interval = strtoul(optarg, &tmp, 0);
 446                                switch (*tmp) {
 447                                case 's':
 448                                        tmp++;
 449                                        break;
 450                                case '\0':
 451                                case 'd':
 452                                case 'D': /* days */
 453                                        interval *= 86400;
 454                                        if (*tmp != '\0')
 455                                                tmp++;
 456                                        break;
 457                                case 'm':
 458                                case 'M': /* months! */
 459                                        interval *= 86400 * 30;
 460                                        tmp++;
 461                                        break;
 462                                case 'w':
 463                                case 'W': /* weeks */
 464                                        interval *= 86400 * 7;
 465                                        tmp++;
 466                                        break;
 467                                }
 468                                if (*tmp || interval > (365 * 86400)) {
 469                                        bb_error_msg_and_die("bad interval - %s", optarg);
 470                                }
 471                                i_flag = 1;
 472                                open_flag = EXT2_FLAG_RW;
 473                                break;
 474                        case 'j':
 475                                if (!journal_size)
 476                                        journal_size = -1;
 477                                open_flag = EXT2_FLAG_RW;
 478                                break;
 479                        case 'J':
 480                                parse_journal_opts(&journal_device, &journal_flags, &journal_size, optarg);
 481                                open_flag = EXT2_FLAG_RW;
 482                                break;
 483                        case 'l':
 484                                l_flag = 1;
 485                                break;
 486                        case 'L':
 487                                new_label = optarg;
 488                                L_flag = 1;
 489                                open_flag = EXT2_FLAG_RW |
 490                                        EXT2_FLAG_JOURNAL_DEV_OK;
 491                                break;
 492                        case 'm':
 493                                reserved_ratio = xatou_range(optarg, 0, 50);
 494                                m_flag = 1;
 495                                open_flag = EXT2_FLAG_RW;
 496                                break;
 497                        case 'M':
 498                                new_last_mounted = optarg;
 499                                M_flag = 1;
 500                                open_flag = EXT2_FLAG_RW;
 501                                break;
 502                        case 'o':
 503                                if (mntopts_cmd) {
 504                                        bb_error_msg_and_die("-o may only be specified once");
 505                                }
 506                                mntopts_cmd = optarg;
 507                                open_flag = EXT2_FLAG_RW;
 508                                break;
 509
 510                        case 'O':
 511                                if (features_cmd) {
 512                                        bb_error_msg_and_die("-O may only be specified once");
 513                                }
 514                                features_cmd = optarg;
 515                                open_flag = EXT2_FLAG_RW;
 516                                break;
 517                        case 'r':
 518                                reserved_blocks = xatoul(optarg);
 519                                r_flag = 1;
 520                                open_flag = EXT2_FLAG_RW;
 521                                break;
 522                        case 's':
 523                                s_flag = atoi(optarg);
 524                                open_flag = EXT2_FLAG_RW;
 525                                break;
 526                        case 'T':
 527                                T_flag = 1;
 528                                last_check_time = parse_time(optarg);
 529                                open_flag = EXT2_FLAG_RW;
 530                                break;
 531                        case 'u':
 532                                resuid = bb_strtoul(optarg, NULL, 10);
 533                                if (errno)
 534                                        resuid = xuname2uid(optarg);
 535                                u_flag = 1;
 536                                open_flag = EXT2_FLAG_RW;
 537                                break;
 538                        case 'U':
 539                                new_UUID = optarg;
 540                                U_flag = 1;
 541                                open_flag = EXT2_FLAG_RW |
 542                                        EXT2_FLAG_JOURNAL_DEV_OK;
 543                                break;
 544                        default:
 545                                bb_show_usage();
 546                }
 547        if (optind < argc - 1 || optind == argc)
 548                bb_show_usage();
 549        if (!open_flag && !l_flag)
 550                bb_show_usage();
 551        io_options = strchr(argv[optind], '?');
 552        if (io_options)
 553                *io_options++ = 0;
 554        device_name = x_blkid_get_devname(argv[optind]);
 555}
 556
 557static void tune2fs_clean_up(void)
 558{
 559        if (ENABLE_FEATURE_CLEAN_UP && device_name) free(device_name);
 560        if (ENABLE_FEATURE_CLEAN_UP && journal_device) free(journal_device);
 561}
 562
 563int tune2fs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 564int tune2fs_main(int argc, char **argv)
 565{
 566        errcode_t retval;
 567        ext2_filsys fs;
 568        struct ext2_super_block *sb;
 569        io_manager io_ptr;
 570
 571        if (ENABLE_FEATURE_CLEAN_UP)
 572                atexit(tune2fs_clean_up);
 573
 574        if (ENABLE_E2LABEL && (applet_name[0] == 'e')) /* e2label */
 575                parse_e2label_options(argc, argv);
 576        else
 577                parse_tune2fs_options(argc, argv);  /* tune2fs */
 578
 579        io_ptr = unix_io_manager;
 580        retval = ext2fs_open2(device_name, io_options, open_flag,
 581                              0, 0, io_ptr, &fs);
 582        if (retval)
 583                bb_error_msg_and_die("No valid superblock on %s", device_name);
 584        sb = fs->super;
 585        if (print_label) {
 586                /* For e2label emulation */
 587                printf("%.*s\n", (int) sizeof(sb->s_volume_name),
 588                       sb->s_volume_name);
 589                return 0;
 590        }
 591        retval = ext2fs_check_if_mounted(device_name, &mount_flags);
 592        if (retval)
 593                bb_error_msg_and_die("cannot determine if %s is mounted", device_name);
 594        /* Normally we only need to write out the superblock */
 595        fs->flags |= EXT2_FLAG_SUPER_ONLY;
 596
 597        if (c_flag) {
 598                sb->s_max_mnt_count = max_mount_count;
 599                ext2fs_mark_super_dirty(fs);
 600                printf("Setting maximal mount count to %d\n", max_mount_count);
 601        }
 602        if (C_flag) {
 603                sb->s_mnt_count = mount_count;
 604                ext2fs_mark_super_dirty(fs);
 605                printf("Setting current mount count to %d\n", mount_count);
 606        }
 607        if (e_flag) {
 608                sb->s_errors = errors;
 609                ext2fs_mark_super_dirty(fs);
 610                printf("Setting error behavior to %d\n", errors);
 611        }
 612        if (g_flag) {
 613                sb->s_def_resgid = resgid;
 614                ext2fs_mark_super_dirty(fs);
 615                printf("Setting reserved blocks gid to %lu\n", resgid);
 616        }
 617        if (i_flag) {
 618                sb->s_checkinterval = interval;
 619                ext2fs_mark_super_dirty(fs);
 620                printf("Setting interval between check %lu seconds\n", interval);
 621        }
 622        if (m_flag) {
 623                sb->s_r_blocks_count = (sb->s_blocks_count / 100)
 624                                * reserved_ratio;
 625                ext2fs_mark_super_dirty(fs);
 626                printf("Setting reserved blocks percentage to %u (%u blocks)\n",
 627                        reserved_ratio, sb->s_r_blocks_count);
 628        }
 629        if (r_flag) {
 630                if (reserved_blocks >= sb->s_blocks_count/2)
 631                        bb_error_msg_and_die("reserved blocks count is too big (%lu)", reserved_blocks);
 632                sb->s_r_blocks_count = reserved_blocks;
 633                ext2fs_mark_super_dirty(fs);
 634                printf("Setting reserved blocks count to %lu\n", reserved_blocks);
 635        }
 636        if (s_flag == 1) {
 637                if (sb->s_feature_ro_compat &
 638                    EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)
 639                        bb_error_msg("\nThe filesystem already has sparse superblocks");
 640                else {
 641                        sb->s_feature_ro_compat |=
 642                                EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
 643                        sb->s_state &= ~EXT2_VALID_FS;
 644                        ext2fs_mark_super_dirty(fs);
 645                        printf("\nSparse superblock flag set.  %s", please_fsck);
 646                }
 647        }
 648        if (s_flag == 0) {
 649                if (!(sb->s_feature_ro_compat &
 650                      EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))
 651                        bb_error_msg("\nThe filesystem already has sparse superblocks disabled");
 652                else {
 653                        sb->s_feature_ro_compat &=
 654                                ~EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
 655                        sb->s_state &= ~EXT2_VALID_FS;
 656                        fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
 657                        ext2fs_mark_super_dirty(fs);
 658                        printf("\nSparse superblock flag cleared.  %s", please_fsck);
 659                }
 660        }
 661        if (T_flag) {
 662                sb->s_lastcheck = last_check_time;
 663                ext2fs_mark_super_dirty(fs);
 664                printf("Setting time filesystem last checked to %s\n",
 665                       ctime(&last_check_time));
 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                        bb_error_msg("Warning: label too long, truncating");
 675                memset(sb->s_volume_name, 0, sizeof(sb->s_volume_name));
 676                safe_strncpy(sb->s_volume_name, new_label,
 677                        sizeof(sb->s_volume_name));
 678                ext2fs_mark_super_dirty(fs);
 679        }
 680        if (M_flag) {
 681                memset(sb->s_last_mounted, 0, sizeof(sb->s_last_mounted));
 682                safe_strncpy(sb->s_last_mounted, new_last_mounted,
 683                        sizeof(sb->s_last_mounted));
 684                ext2fs_mark_super_dirty(fs);
 685        }
 686        if (mntopts_cmd)
 687                update_mntopts(fs, mntopts_cmd);
 688        if (features_cmd)
 689                update_feature_set(fs, features_cmd);
 690        if (journal_size || journal_device)
 691                add_journal(fs);
 692
 693        if (U_flag) {
 694                if ((strcasecmp(new_UUID, "null") == 0) ||
 695                    (strcasecmp(new_UUID, "clear") == 0)) {
 696                        uuid_clear(sb->s_uuid);
 697                } else if (strcasecmp(new_UUID, "time") == 0) {
 698                        uuid_generate_time(sb->s_uuid);
 699                } else if (strcasecmp(new_UUID, "random") == 0) {
 700                        uuid_generate(sb->s_uuid);
 701                } else if (uuid_parse(new_UUID, sb->s_uuid)) {
 702                        bb_error_msg_and_die("Invalid UUID format");
 703                }
 704                ext2fs_mark_super_dirty(fs);
 705        }
 706
 707        if (l_flag)
 708                list_super (sb);
 709        return (ext2fs_close (fs) ? 1 : 0);
 710}
 711