blob: a2d22b6a0ad1479f7825edf7e61d38d93456f0a6 [file] [log] [blame]
Theodore Ts'o3839e651997-04-26 13:21:57 +00001/*
Theodore Ts'o4d0f2282001-04-23 20:58:03 +00002 * tune2fs.c - Change the file system parameters on an ext2 file system
Theodore Ts'o3839e651997-04-26 13:21:57 +00003 *
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 *
Theodore Ts'o4d0f2282001-04-23 20:58:03 +00008 * Copyright 1995, 1996, 1997, 1998, 1999, 2000 by Theodore Ts'o.
Theodore Ts'o19c78dc1997-04-29 16:17:09 +00009 *
10 * %Begin-Header%
11 * This file may be redistributed under the terms of the GNU Public
12 * License.
13 * %End-Header%
Theodore Ts'o3839e651997-04-26 13:21:57 +000014 */
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>
Theodore Ts'of3db3561997-04-26 13:34:30 +000029#include <grp.h>
Theodore Ts'oa418d3a1997-04-26 14:00:26 +000030#ifdef HAVE_GETOPT_H
Theodore Ts'o3839e651997-04-26 13:21:57 +000031#include <getopt.h>
Theodore Ts'o373b8332000-04-03 16:22:35 +000032#else
33extern char *optarg;
34extern int optind;
Theodore Ts'oa418d3a1997-04-26 14:00:26 +000035#endif
Theodore Ts'of3db3561997-04-26 13:34:30 +000036#include <pwd.h>
Theodore Ts'o3839e651997-04-26 13:21:57 +000037#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <time.h>
41#include <unistd.h>
Theodore Ts'of3db3561997-04-26 13:34:30 +000042#include <sys/types.h>
Theodore Ts'o3839e651997-04-26 13:21:57 +000043
Theodore Ts'o54c637d2001-05-14 11:45:38 +000044#include "ext2fs/ext2_fs.h"
Theodore Ts'o3839e651997-04-26 13:21:57 +000045#include "ext2fs/ext2fs.h"
46#include "et/com_err.h"
Theodore Ts'o1e3472c1997-04-29 14:53:37 +000047#include "uuid/uuid.h"
Theodore Ts'o3839e651997-04-26 13:21:57 +000048#include "e2p/e2p.h"
Theodore Ts'odc2ec522001-01-18 01:51:15 +000049#include "jfs_user.h"
Theodore Ts'o63985322001-01-03 17:02:13 +000050#include "util.h"
Theodore Ts'oed1b33e2003-03-01 19:29:01 -050051#include "blkid/blkid.h"
Theodore Ts'o3839e651997-04-26 13:21:57 +000052
53#include "../version.h"
Theodore Ts'od9c56d32000-02-08 00:47:55 +000054#include "nls-enable.h"
Theodore Ts'o3839e651997-04-26 13:21:57 +000055
56const char * program_name = "tune2fs";
Theodore Ts'o63985322001-01-03 17:02:13 +000057char * device_name;
Theodore Ts'oc8c071a2001-01-11 16:08:23 +000058char * new_label, *new_last_mounted, *new_UUID;
Theodore Ts'o4d0f2282001-04-23 20:58:03 +000059static int c_flag, C_flag, e_flag, f_flag, g_flag, i_flag, l_flag, L_flag;
Theodore Ts'od4de4aa2001-12-26 08:58:01 -050060static int m_flag, M_flag, r_flag, s_flag = -1, u_flag, U_flag, T_flag;
61static time_t last_check_time;
Theodore Ts'o83238152001-01-09 00:16:26 +000062static int print_label;
Theodore Ts'o63985322001-01-03 17:02:13 +000063static int max_mount_count, mount_count, mount_flags;
64static unsigned long interval, reserved_ratio, reserved_blocks;
65static unsigned long resgid, resuid;
66static unsigned short errors;
Theodore Ts'o83238152001-01-09 00:16:26 +000067static int open_flag;
68static char *features_cmd;
Theodore Ts'oa0c3fd52002-10-15 17:43:43 -040069static char *mntopts_cmd;
Theodore Ts'o3839e651997-04-26 13:21:57 +000070
Theodore Ts'o63985322001-01-03 17:02:13 +000071int journal_size, journal_flags;
72char *journal_device;
73
74static const char *please_fsck = N_("Please run e2fsck on the filesystem.\n");
Theodore Ts'o1e3472c1997-04-29 14:53:37 +000075
Theodore Ts'o3e699062002-10-13 23:56:28 -040076void do_findfs(int argc, char **argv);
77
Theodore Ts'o818180c1998-06-27 05:11:14 +000078static void usage(void)
Theodore Ts'o3839e651997-04-26 13:21:57 +000079{
Theodore Ts'ob21e38a2001-01-01 15:26:58 +000080 fprintf(stderr,
81 _("Usage: %s [-c max-mounts-count] [-e errors-behavior] "
82 "[-g group]\n"
Theodore Ts'oa0c3fd52002-10-15 17:43:43 -040083 "\t[-i interval[d|m|w]] [-j] [-J journal-options]\n"
84 "\t[-l] [-s sparse-flag] [-m reserved-blocks-percent]\n"
85 "\t[-o [^]mount-options[,...]] [-r reserved-blocks-count]\n"
86 "\t[-u user] [-C mount-count] [-L volume-label] "
87 "[-M last-mounted-dir]\n"
Theodore Ts'od4de4aa2001-12-26 08:58:01 -050088 "\t[-O [^]feature[,...]] [-T last-check-time] [-U UUID]"
89 " device\n"), program_name);
Theodore Ts'o3839e651997-04-26 13:21:57 +000090 exit (1);
91}
92
Theodore Ts'o896938d1999-10-23 01:04:50 +000093static __u32 ok_features[3] = {
Theodore Ts'o843049c2002-09-22 15:37:40 -040094 EXT3_FEATURE_COMPAT_HAS_JOURNAL |
95 EXT2_FEATURE_COMPAT_DIR_INDEX, /* Compat */
Theodore Ts'o896938d1999-10-23 01:04:50 +000096 EXT2_FEATURE_INCOMPAT_FILETYPE, /* Incompat */
97 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER /* R/O compat */
98};
99
Theodore Ts'o63985322001-01-03 17:02:13 +0000100/*
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000101 * Remove an external journal from the filesystem
102 */
103static void remove_journal_device(ext2_filsys fs)
104{
Theodore Ts'o4ea7bd02001-12-16 23:23:37 -0500105 char *journal_path;
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000106 ext2_filsys jfs;
107 char buf[1024];
108 journal_superblock_t *jsb;
109 int i, nr_users;
110 errcode_t retval;
Theodore Ts'o4d0f2282001-04-23 20:58:03 +0000111 int commit_remove_journal = 0;
Theodore Ts'o2a29f132003-05-05 12:08:47 -0400112 io_manager io_ptr;
Theodore Ts'o4d0f2282001-04-23 20:58:03 +0000113
114 if (f_flag)
115 commit_remove_journal = 1; /* force removal even if error */
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000116
Andreas Dilger2d155762001-08-17 03:48:11 -0600117 uuid_unparse(fs->super->s_journal_uuid, buf);
Theodore Ts'oed1b33e2003-03-01 19:29:01 -0500118 journal_path = blkid_get_devname(NULL, "UUID", buf);
Andreas Dilger2d155762001-08-17 03:48:11 -0600119
Theodore Ts'o4ea7bd02001-12-16 23:23:37 -0500120 if (!journal_path) {
121 journal_path =
Andreas Dilger2d155762001-08-17 03:48:11 -0600122 ext2fs_find_block_device(fs->super->s_journal_dev);
Theodore Ts'o4ea7bd02001-12-16 23:23:37 -0500123 if (!journal_path)
Andreas Dilger2d155762001-08-17 03:48:11 -0600124 return;
125 }
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000126
Theodore Ts'o2a29f132003-05-05 12:08:47 -0400127#ifdef CONFIG_TESTIO_DEBUG
128 io_ptr = test_io_manager;
129 test_io_backing_manager = unix_io_manager;
130#else
131 io_ptr = unix_io_manager;
132#endif
Theodore Ts'o4ea7bd02001-12-16 23:23:37 -0500133 retval = ext2fs_open(journal_path, EXT2_FLAG_RW|
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000134 EXT2_FLAG_JOURNAL_DEV_OK, 0,
Theodore Ts'o2a29f132003-05-05 12:08:47 -0400135 fs->blocksize, io_ptr, &jfs);
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000136 if (retval) {
137 com_err(program_name, retval,
138 _("while trying to open external journal"));
Theodore Ts'o4d0f2282001-04-23 20:58:03 +0000139 goto no_valid_journal;
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000140 }
141 if (!(jfs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
Theodore Ts'o7141b542001-08-15 19:17:37 -0400142 fprintf(stderr, _("%s is not a journal device.\n"),
Theodore Ts'o4ea7bd02001-12-16 23:23:37 -0500143 journal_path);
Theodore Ts'o4d0f2282001-04-23 20:58:03 +0000144 goto no_valid_journal;
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000145 }
146
147 /* Get the journal superblock */
148 if ((retval = io_channel_read_blk(jfs->io, 1, -1024, buf))) {
149 com_err(program_name, retval,
150 _("while reading journal superblock"));
Theodore Ts'o4d0f2282001-04-23 20:58:03 +0000151 goto no_valid_journal;
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000152 }
153
154 jsb = (journal_superblock_t *) buf;
155 if ((jsb->s_header.h_magic != (unsigned) ntohl(JFS_MAGIC_NUMBER)) ||
156 (jsb->s_header.h_blocktype != (unsigned) ntohl(JFS_SUPERBLOCK_V2))) {
157 fprintf(stderr, _("Journal superblock not found!\n"));
Theodore Ts'o4d0f2282001-04-23 20:58:03 +0000158 goto no_valid_journal;
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000159 }
160
161 /* Find the filesystem UUID */
162 nr_users = ntohl(jsb->s_nr_users);
163 for (i=0; i < nr_users; i++) {
164 if (memcmp(fs->super->s_uuid,
165 &jsb->s_users[i*16], 16) == 0)
166 break;
167 }
168 if (i >= nr_users) {
Theodore Ts'o7141b542001-08-15 19:17:37 -0400169 fprintf(stderr,
170 _("Filesystem's UUID not found on journal device.\n"));
Theodore Ts'o4d0f2282001-04-23 20:58:03 +0000171 commit_remove_journal = 1;
172 goto no_valid_journal;
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000173 }
174 nr_users--;
175 for (i=0; i < nr_users; i++)
176 memcpy(&jsb->s_users[i*16], &jsb->s_users[(i+1)*16], 16);
177 jsb->s_nr_users = htonl(nr_users);
178
179 /* Write back the journal superblock */
180 if ((retval = io_channel_write_blk(jfs->io, 1, -1024, buf))) {
181 com_err(program_name, retval,
182 "while writing journal superblock.");
Theodore Ts'o4d0f2282001-04-23 20:58:03 +0000183 goto no_valid_journal;
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000184 }
185
Theodore Ts'o4d0f2282001-04-23 20:58:03 +0000186 commit_remove_journal = 1;
187
188no_valid_journal:
189 if (commit_remove_journal == 0) {
Theodore Ts'o7141b542001-08-15 19:17:37 -0400190 fprintf(stderr, _("Journal NOT removed\n"));
Theodore Ts'o4d0f2282001-04-23 20:58:03 +0000191 exit(1);
192 }
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000193 fs->super->s_journal_dev = 0;
Theodore Ts'oed1b33e2003-03-01 19:29:01 -0500194 uuid_clear(fs->super->s_journal_uuid);
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000195 ext2fs_mark_super_dirty(fs);
Theodore Ts'o4d0f2282001-04-23 20:58:03 +0000196 printf(_("Journal removed\n"));
Theodore Ts'o4ea7bd02001-12-16 23:23:37 -0500197 free(journal_path);
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000198}
199
Theodore Ts'o194686b2001-07-31 12:03:23 -0400200/* Helper function for remove_journal_inode */
201static int release_blocks_proc(ext2_filsys fs, blk_t *blocknr,
202 int blockcnt, void *private)
203{
204 blk_t block;
205 int group;
206
207 block = *blocknr;
208 ext2fs_unmark_block_bitmap(fs->block_map,block);
209 group = ext2fs_group_of_blk(fs, block);
210 fs->group_desc[group].bg_free_blocks_count++;
211 fs->super->s_free_blocks_count++;
212 return 0;
213}
214
215/*
216 * Remove the journal inode from the filesystem
217 */
218static void remove_journal_inode(ext2_filsys fs)
219{
220 struct ext2_inode inode;
221 errcode_t retval;
222 ino_t ino = fs->super->s_journal_inum;
Theodore Ts'o194686b2001-07-31 12:03:23 -0400223
224 retval = ext2fs_read_inode(fs, ino, &inode);
225 if (retval) {
226 com_err(program_name, retval,
227 _("while reading journal inode"));
228 exit(1);
229 }
230 if (ino == EXT2_JOURNAL_INO) {
231 retval = ext2fs_read_bitmaps(fs);
232 if (retval) {
233 com_err(program_name, retval,
234 _("while reading bitmaps"));
235 exit(1);
236 }
237 retval = ext2fs_block_iterate(fs, ino, 0, NULL,
238 release_blocks_proc, NULL);
239 if (retval) {
240 com_err(program_name, retval,
241 _("while clearing journal inode"));
242 exit(1);
243 }
244 memset(&inode, 0, sizeof(inode));
245 ext2fs_mark_bb_dirty(fs);
Theodore Ts'o194686b2001-07-31 12:03:23 -0400246 fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
247 } else
248 inode.i_flags &= ~EXT2_IMMUTABLE_FL;
249 retval = ext2fs_write_inode(fs, ino, &inode);
250 if (retval) {
251 com_err(program_name, retval,
252 _("while writing journal inode"));
253 exit(1);
254 }
255 fs->super->s_journal_inum = 0;
256 ext2fs_mark_super_dirty(fs);
257}
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000258
259/*
Theodore Ts'oa0c3fd52002-10-15 17:43:43 -0400260 * Update the default mount options
261 */
262static void update_mntopts(ext2_filsys fs, char *mntopts)
263{
264 struct ext2_super_block *sb= fs->super;
265
266 if (e2p_edit_mntopts(mntopts, &sb->s_default_mount_opts, ~0)) {
267 fprintf(stderr, _("Invalid mount option set: %s\n"),
268 mntopts);
269 exit(1);
270 }
271 ext2fs_mark_super_dirty(fs);
272}
273
274/*
Theodore Ts'o63985322001-01-03 17:02:13 +0000275 * Update the feature set as provided by the user.
276 */
Theodore Ts'oc8c071a2001-01-11 16:08:23 +0000277static void update_feature_set(ext2_filsys fs, char *features)
Theodore Ts'o63985322001-01-03 17:02:13 +0000278{
279 int sparse, old_sparse, filetype, old_filetype;
Theodore Ts'o843049c2002-09-22 15:37:40 -0400280 int journal, old_journal, dxdir, old_dxdir;
Theodore Ts'o63985322001-01-03 17:02:13 +0000281 struct ext2_super_block *sb= fs->super;
Theodore Ts'o63985322001-01-03 17:02:13 +0000282
283 old_sparse = sb->s_feature_ro_compat &
284 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
285 old_filetype = sb->s_feature_incompat &
286 EXT2_FEATURE_INCOMPAT_FILETYPE;
287 old_journal = sb->s_feature_compat &
288 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
Theodore Ts'o843049c2002-09-22 15:37:40 -0400289 old_dxdir = sb->s_feature_compat &
290 EXT2_FEATURE_COMPAT_DIR_INDEX;
Theodore Ts'oc8c071a2001-01-11 16:08:23 +0000291 if (e2p_edit_feature(features, &sb->s_feature_compat,
Theodore Ts'o63985322001-01-03 17:02:13 +0000292 ok_features)) {
293 fprintf(stderr, _("Invalid filesystem option set: %s\n"),
Theodore Ts'oc8c071a2001-01-11 16:08:23 +0000294 features);
Theodore Ts'o63985322001-01-03 17:02:13 +0000295 exit(1);
296 }
297 sparse = sb->s_feature_ro_compat &
298 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
299 filetype = sb->s_feature_incompat &
300 EXT2_FEATURE_INCOMPAT_FILETYPE;
301 journal = sb->s_feature_compat &
302 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
Theodore Ts'o843049c2002-09-22 15:37:40 -0400303 dxdir = sb->s_feature_compat &
304 EXT2_FEATURE_COMPAT_DIR_INDEX;
Theodore Ts'o63985322001-01-03 17:02:13 +0000305 if (old_journal && !journal) {
306 if ((mount_flags & EXT2_MF_MOUNTED) &&
307 !(mount_flags & EXT2_MF_READONLY)) {
308 fprintf(stderr,
Theodore Ts'o8d641742001-05-14 04:12:27 +0000309 _("The has_journal flag may only be "
Theodore Ts'o63985322001-01-03 17:02:13 +0000310 "cleared when the filesystem is\n"
311 "unmounted or mounted "
312 "read-only.\n"));
313 exit(1);
314 }
315 if (sb->s_feature_incompat &
316 EXT3_FEATURE_INCOMPAT_RECOVER) {
317 fprintf(stderr,
Theodore Ts'o8d641742001-05-14 04:12:27 +0000318 _("The needs_recovery flag is set. "
Theodore Ts'o63985322001-01-03 17:02:13 +0000319 "Please run e2fsck before clearing\n"
Theodore Ts'oe549d0a2001-05-25 16:38:48 +0000320 "the has_journal flag.\n"));
Theodore Ts'o63985322001-01-03 17:02:13 +0000321 exit(1);
322 }
Theodore Ts'o63985322001-01-03 17:02:13 +0000323 if (sb->s_journal_inum) {
Theodore Ts'o194686b2001-07-31 12:03:23 -0400324 remove_journal_inode(fs);
Theodore Ts'o63985322001-01-03 17:02:13 +0000325 }
Theodore Ts'ode49f012001-07-30 16:31:30 -0400326 if (sb->s_journal_dev) {
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000327 remove_journal_device(fs);
Theodore Ts'ode49f012001-07-30 16:31:30 -0400328 }
Theodore Ts'o63985322001-01-03 17:02:13 +0000329 }
330 if (journal && !old_journal) {
331 /*
332 * If adding a journal flag, let the create journal
333 * code below handle creating setting the flag and
334 * creating the journal. We supply a default size if
335 * necessary.
336 */
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000337 if (!journal_size)
338 journal_size = -1;
Theodore Ts'o08dd8302001-01-14 16:25:58 +0000339 sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
Theodore Ts'o63985322001-01-03 17:02:13 +0000340 }
Theodore Ts'o843049c2002-09-22 15:37:40 -0400341 if (dxdir && !old_dxdir) {
342 if (!sb->s_def_hash_version)
343 sb->s_def_hash_version = EXT2_HASH_TEA;
344 if (uuid_is_null((unsigned char *) sb->s_hash_seed))
345 uuid_generate((unsigned char *) sb->s_hash_seed);
346 }
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000347
Theodore Ts'o63985322001-01-03 17:02:13 +0000348 if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
349 (sb->s_feature_compat || sb->s_feature_ro_compat ||
350 sb->s_feature_incompat))
351 ext2fs_update_dynamic_rev(fs);
352 if ((sparse != old_sparse) ||
Theodore Ts'o194686b2001-07-31 12:03:23 -0400353 (filetype != old_filetype)) {
Theodore Ts'o63985322001-01-03 17:02:13 +0000354 sb->s_state &= ~EXT2_VALID_FS;
355 printf("\n%s\n", _(please_fsck));
356 }
357 ext2fs_mark_super_dirty(fs);
358}
359
360/*
361 * Add a journal to the filesystem.
362 */
363static void add_journal(ext2_filsys fs)
364{
365 unsigned long journal_blocks;
366 errcode_t retval;
Theodore Ts'o16ed5b32001-01-16 07:47:31 +0000367 ext2_filsys jfs;
Theodore Ts'o2a29f132003-05-05 12:08:47 -0400368 io_manager io_ptr;
Theodore Ts'o63985322001-01-03 17:02:13 +0000369
370 if (fs->super->s_feature_compat &
371 EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
372 fprintf(stderr, _("The filesystem already has a journal.\n"));
Andreas Dilger2d155762001-08-17 03:48:11 -0600373 goto err;
Theodore Ts'o63985322001-01-03 17:02:13 +0000374 }
Theodore Ts'o63985322001-01-03 17:02:13 +0000375 if (journal_device) {
376 check_plausibility(journal_device);
377 check_mount(journal_device, 0, _("journal"));
Theodore Ts'o2a29f132003-05-05 12:08:47 -0400378#ifdef CONFIG_TESTIO_DEBUG
379 io_ptr = test_io_manager;
380 test_io_backing_manager = unix_io_manager;
381#else
382 io_ptr = unix_io_manager;
383#endif
Theodore Ts'o16ed5b32001-01-16 07:47:31 +0000384 retval = ext2fs_open(journal_device, EXT2_FLAG_RW|
385 EXT2_FLAG_JOURNAL_DEV_OK, 0,
Theodore Ts'o2a29f132003-05-05 12:08:47 -0400386 fs->blocksize, io_ptr, &jfs);
Theodore Ts'o16ed5b32001-01-16 07:47:31 +0000387 if (retval) {
388 com_err(program_name, retval,
Theodore Ts'o1d08d9b2001-04-17 01:01:49 +0000389 _("\n\twhile trying to open journal on %s\n"),
Theodore Ts'o16ed5b32001-01-16 07:47:31 +0000390 journal_device);
Andreas Dilger2d155762001-08-17 03:48:11 -0600391 goto err;
Theodore Ts'o16ed5b32001-01-16 07:47:31 +0000392 }
Theodore Ts'o63985322001-01-03 17:02:13 +0000393 printf(_("Creating journal on device %s: "),
394 journal_device);
Theodore Ts'o4055ef72001-01-14 16:11:14 +0000395 fflush(stdout);
Andreas Dilger2d155762001-08-17 03:48:11 -0600396
Theodore Ts'o16ed5b32001-01-16 07:47:31 +0000397 retval = ext2fs_add_journal_device(fs, jfs);
Andreas Dilger2d155762001-08-17 03:48:11 -0600398 ext2fs_close(jfs);
Theodore Ts'o63985322001-01-03 17:02:13 +0000399 if (retval) {
400 com_err (program_name, retval,
Theodore Ts'o8d641742001-05-14 04:12:27 +0000401 _("while adding filesystem to journal on %s"),
Theodore Ts'o63985322001-01-03 17:02:13 +0000402 journal_device);
Andreas Dilger2d155762001-08-17 03:48:11 -0600403 goto err;
Theodore Ts'o63985322001-01-03 17:02:13 +0000404 }
405 printf(_("done\n"));
406 } else if (journal_size) {
Theodore Ts'o63985322001-01-03 17:02:13 +0000407 printf(_("Creating journal inode: "));
408 fflush(stdout);
Theodore Ts'o2537b6d2001-03-26 20:07:13 +0000409 journal_blocks = figure_journal_size(journal_size, fs);
410
Theodore Ts'o63985322001-01-03 17:02:13 +0000411 retval = ext2fs_add_journal_inode(fs, journal_blocks,
412 journal_flags);
413 if (retval) {
Theodore Ts'o7141b542001-08-15 19:17:37 -0400414 fprintf(stderr, "\n");
Theodore Ts'o63985322001-01-03 17:02:13 +0000415 com_err(program_name, retval,
Theodore Ts'o1d08d9b2001-04-17 01:01:49 +0000416 _("\n\twhile trying to create journal file"));
Theodore Ts'o63985322001-01-03 17:02:13 +0000417 exit(1);
Theodore Ts'o1d08d9b2001-04-17 01:01:49 +0000418 } else
419 printf(_("done\n"));
Theodore Ts'o63985322001-01-03 17:02:13 +0000420 /*
421 * If the filesystem wasn't mounted, we need to force
422 * the block group descriptors out.
423 */
424 if ((mount_flags & EXT2_MF_MOUNTED) == 0)
425 fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
426 }
Theodore Ts'o66cf2f62001-06-14 06:42:44 +0000427 print_check_message(fs);
Andreas Dilger2d155762001-08-17 03:48:11 -0600428 return;
429
430err:
431 if (journal_device)
432 free(journal_device);
433 exit(1);
Theodore Ts'o63985322001-01-03 17:02:13 +0000434}
435
Theodore Ts'o896938d1999-10-23 01:04:50 +0000436
Theodore Ts'oc8c071a2001-01-11 16:08:23 +0000437static void parse_e2label_options(int argc, char ** argv)
Theodore Ts'o83238152001-01-09 00:16:26 +0000438{
439 if ((argc < 2) || (argc > 3)) {
440 fprintf(stderr, _("Usage: e2label device [newlabel]\n"));
441 exit(1);
442 }
Theodore Ts'o332f2c22003-03-06 12:58:33 -0500443 device_name = blkid_get_devname(NULL, argv[1], NULL);
Theodore Ts'o83238152001-01-09 00:16:26 +0000444 if (argc == 3) {
Andreas Dilger2d155762001-08-17 03:48:11 -0600445 open_flag = EXT2_FLAG_RW | EXT2_FLAG_JOURNAL_DEV_OK;
Theodore Ts'o83238152001-01-09 00:16:26 +0000446 L_flag = 1;
447 new_label = argv[2];
448 } else
449 print_label++;
450}
451
Theodore Ts'od4de4aa2001-12-26 08:58:01 -0500452static time_t parse_time(char *str)
453{
454 struct tm ts;
455
456 if (strcmp(str, "now") == 0) {
457 return (time(0));
458 }
459 memset(&ts, 0, sizeof(ts));
Theodore Ts'obc7c14e2003-05-03 16:40:09 -0400460#ifdef HAVE_STRPTIME
Theodore Ts'od4de4aa2001-12-26 08:58:01 -0500461 strptime(optarg, "%Y%m%d%H%M%S", &ts);
Theodore Ts'obc7c14e2003-05-03 16:40:09 -0400462#else
463 sscanf(optarg, "%4d%2d%2d%2d%2d%2d", &ts.tm_year, &ts.tm_mon,
464 &ts.tm_mday, &ts.tm_hour, &ts.tm_min, &ts.tm_sec);
465 ts.tm_year -= 1900;
466 ts.tm_mon -= 1;
467 if (ts.tm_year < 0 || ts.tm_mon < 0 || ts.tm_mon > 11 ||
468 ts.tm_mday < 0 || ts.tm_mday > 31 || ts.tm_hour > 23 ||
469 ts.tm_min > 59 || ts.tm_sec > 61)
470 ts.tm_mday = 0;
471#endif
Theodore Ts'od4de4aa2001-12-26 08:58:01 -0500472 if (ts.tm_mday == 0) {
473 com_err(program_name, 0,
474 _("Couldn't parse date/time specifier: %s"),
475 str);
476 usage();
477 }
478 return (mktime(&ts));
479}
Theodore Ts'o83238152001-01-09 00:16:26 +0000480
Theodore Ts'oc8c071a2001-01-11 16:08:23 +0000481static void parse_tune2fs_options(int argc, char **argv)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000482{
Theodore Ts'o519149f1997-10-25 03:49:49 +0000483 int c;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000484 char * tmp;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000485 struct group * gr;
486 struct passwd * pw;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000487
Theodore Ts'o0f8973f2001-08-27 12:44:23 -0400488 printf("tune2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE);
Theodore Ts'oa0c3fd52002-10-15 17:43:43 -0400489 while ((c = getopt(argc, argv, "c:e:fg:i:jlm:o:r:s:u:C:J:L:M:O:T:U:")) != EOF)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000490 switch (c)
491 {
492 case 'c':
Theodore Ts'o45d9e2f2000-07-07 03:12:54 +0000493 max_mount_count = strtol (optarg, &tmp, 0);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000494 if (*tmp || max_mount_count > 16000) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000495 com_err (program_name, 0,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000496 _("bad mounts count - %s"),
Theodore Ts'o3839e651997-04-26 13:21:57 +0000497 optarg);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000498 usage();
Theodore Ts'o3839e651997-04-26 13:21:57 +0000499 }
Theodore Ts'oce57f142001-04-26 04:25:39 +0000500 if (max_mount_count == 0)
501 max_mount_count = -1;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000502 c_flag = 1;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000503 open_flag = EXT2_FLAG_RW;
504 break;
505 case 'C':
506 mount_count = strtoul (optarg, &tmp, 0);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000507 if (*tmp || mount_count > 16000) {
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000508 com_err (program_name, 0,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000509 _("bad mounts count - %s"),
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000510 optarg);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000511 usage();
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000512 }
513 C_flag = 1;
514 open_flag = EXT2_FLAG_RW;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000515 break;
516 case 'e':
517 if (strcmp (optarg, "continue") == 0)
518 errors = EXT2_ERRORS_CONTINUE;
519 else if (strcmp (optarg, "remount-ro") == 0)
520 errors = EXT2_ERRORS_RO;
521 else if (strcmp (optarg, "panic") == 0)
522 errors = EXT2_ERRORS_PANIC;
Theodore Ts'o818180c1998-06-27 05:11:14 +0000523 else {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000524 com_err (program_name, 0,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000525 _("bad error behavior - %s"),
Theodore Ts'o3839e651997-04-26 13:21:57 +0000526 optarg);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000527 usage();
Theodore Ts'o3839e651997-04-26 13:21:57 +0000528 }
529 e_flag = 1;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000530 open_flag = EXT2_FLAG_RW;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000531 break;
Theodore Ts'o4d0f2282001-04-23 20:58:03 +0000532 case 'f': /* Force */
533 f_flag = 1;
534 break;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000535 case 'g':
536 resgid = strtoul (optarg, &tmp, 0);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000537 if (*tmp) {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000538 gr = getgrnam (optarg);
539 if (gr == NULL)
540 tmp = optarg;
Theodore Ts'oa418d3a1997-04-26 14:00:26 +0000541 else {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000542 resgid = gr->gr_gid;
Theodore Ts'oa418d3a1997-04-26 14:00:26 +0000543 *tmp =0;
544 }
Theodore Ts'of3db3561997-04-26 13:34:30 +0000545 }
Theodore Ts'o818180c1998-06-27 05:11:14 +0000546 if (*tmp) {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000547 com_err (program_name, 0,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000548 _("bad gid/group name - %s"),
Theodore Ts'of3db3561997-04-26 13:34:30 +0000549 optarg);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000550 usage();
Theodore Ts'of3db3561997-04-26 13:34:30 +0000551 }
552 g_flag = 1;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000553 open_flag = EXT2_FLAG_RW;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000554 break;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000555 case 'i':
556 interval = strtoul (optarg, &tmp, 0);
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000557 switch (*tmp) {
558 case 's':
559 tmp++;
560 break;
561 case '\0':
562 case 'd':
563 case 'D': /* days */
564 interval *= 86400;
565 if (*tmp != '\0')
Theodore Ts'o3839e651997-04-26 13:21:57 +0000566 tmp++;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000567 break;
568 case 'm':
569 case 'M': /* months! */
570 interval *= 86400 * 30;
571 tmp++;
572 break;
573 case 'w':
574 case 'W': /* weeks */
575 interval *= 86400 * 7;
576 tmp++;
577 break;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000578 }
Theodore Ts'o818180c1998-06-27 05:11:14 +0000579 if (*tmp || interval > (365 * 86400)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000580 com_err (program_name, 0,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000581 _("bad interval - %s"), optarg);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000582 usage();
Theodore Ts'o3839e651997-04-26 13:21:57 +0000583 }
584 i_flag = 1;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000585 open_flag = EXT2_FLAG_RW;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000586 break;
Theodore Ts'o63985322001-01-03 17:02:13 +0000587 case 'j':
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000588 if (!journal_size)
589 journal_size = -1;
Theodore Ts'o4d0f2282001-04-23 20:58:03 +0000590 open_flag = EXT2_FLAG_RW;
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000591 break;
592 case 'J':
593 parse_journal_opts(optarg);
Theodore Ts'o63985322001-01-03 17:02:13 +0000594 open_flag = EXT2_FLAG_RW;
595 break;
Theodore Ts'o08dd8302001-01-14 16:25:58 +0000596 case 'l':
597 l_flag = 1;
598 break;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000599 case 'L':
600 new_label = optarg;
601 L_flag = 1;
Andreas Dilger2d155762001-08-17 03:48:11 -0600602 open_flag = EXT2_FLAG_RW |
603 EXT2_FLAG_JOURNAL_DEV_OK;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000604 break;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000605 case 'm':
606 reserved_ratio = strtoul (optarg, &tmp, 0);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000607 if (*tmp || reserved_ratio > 50) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000608 com_err (program_name, 0,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000609 _("bad reserved block ratio - %s"),
Theodore Ts'o3839e651997-04-26 13:21:57 +0000610 optarg);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000611 usage();
Theodore Ts'o3839e651997-04-26 13:21:57 +0000612 }
613 m_flag = 1;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000614 open_flag = EXT2_FLAG_RW;
615 break;
616 case 'M':
617 new_last_mounted = optarg;
618 M_flag = 1;
619 open_flag = EXT2_FLAG_RW;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000620 break;
Theodore Ts'oa0c3fd52002-10-15 17:43:43 -0400621 case 'o':
622 if (mntopts_cmd) {
623 com_err (program_name, 0,
624 _("-o may only be specified once"));
625 usage();
626 }
627 mntopts_cmd = optarg;
628 open_flag = EXT2_FLAG_RW;
629 break;
630
Theodore Ts'o896938d1999-10-23 01:04:50 +0000631 case 'O':
Theodore Ts'od2586682001-08-15 11:03:58 -0400632 if (features_cmd) {
633 com_err (program_name, 0,
634 _("-O may only be specified once"));
635 usage();
636 }
Theodore Ts'o896938d1999-10-23 01:04:50 +0000637 features_cmd = optarg;
638 open_flag = EXT2_FLAG_RW;
639 break;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000640 case 'r':
641 reserved_blocks = strtoul (optarg, &tmp, 0);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000642 if (*tmp) {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000643 com_err (program_name, 0,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000644 _("bad reserved blocks count - %s"),
Theodore Ts'of3db3561997-04-26 13:34:30 +0000645 optarg);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000646 usage();
Theodore Ts'of3db3561997-04-26 13:34:30 +0000647 }
648 r_flag = 1;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000649 open_flag = EXT2_FLAG_RW;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000650 break;
Theodore Ts'o521e3681997-04-29 17:48:10 +0000651 case 's':
652 s_flag = atoi(optarg);
653 open_flag = EXT2_FLAG_RW;
654 break;
Theodore Ts'od4de4aa2001-12-26 08:58:01 -0500655 case 'T':
656 T_flag = 1;
657 last_check_time = parse_time(optarg);
658 open_flag = EXT2_FLAG_RW;
659 break;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000660 case 'u':
661 resuid = strtoul (optarg, &tmp, 0);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000662 if (*tmp) {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000663 pw = getpwnam (optarg);
664 if (pw == NULL)
665 tmp = optarg;
Theodore Ts'oa418d3a1997-04-26 14:00:26 +0000666 else {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000667 resuid = pw->pw_uid;
Theodore Ts'oa418d3a1997-04-26 14:00:26 +0000668 *tmp = 0;
669 }
Theodore Ts'of3db3561997-04-26 13:34:30 +0000670 }
Theodore Ts'o818180c1998-06-27 05:11:14 +0000671 if (*tmp) {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000672 com_err (program_name, 0,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000673 _("bad uid/user name - %s"),
Theodore Ts'of3db3561997-04-26 13:34:30 +0000674 optarg);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000675 usage();
Theodore Ts'of3db3561997-04-26 13:34:30 +0000676 }
677 u_flag = 1;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000678 open_flag = EXT2_FLAG_RW;
679 break;
680 case 'U':
681 new_UUID = optarg;
682 U_flag = 1;
Andreas Dilger2d155762001-08-17 03:48:11 -0600683 open_flag = EXT2_FLAG_RW |
684 EXT2_FLAG_JOURNAL_DEV_OK;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000685 break;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000686 default:
Theodore Ts'o818180c1998-06-27 05:11:14 +0000687 usage();
Theodore Ts'o3839e651997-04-26 13:21:57 +0000688 }
689 if (optind < argc - 1 || optind == argc)
Theodore Ts'o818180c1998-06-27 05:11:14 +0000690 usage();
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000691 if (!open_flag && !l_flag)
692 usage();
Theodore Ts'o332f2c22003-03-06 12:58:33 -0500693 device_name = blkid_get_devname(NULL, argv[optind], NULL);
Theodore Ts'o118d7da2002-08-17 23:01:22 -0400694}
Theodore Ts'o83238152001-01-09 00:16:26 +0000695
Theodore Ts'o3e699062002-10-13 23:56:28 -0400696void do_findfs(int argc, char **argv)
Theodore Ts'o118d7da2002-08-17 23:01:22 -0400697{
698 char *dev;
699
700 if ((argc != 2) ||
701 (strncmp(argv[1], "LABEL=", 6) && strncmp(argv[1], "UUID=", 5))) {
702 fprintf(stderr, "Usage: findfs LABEL=<label>|UUID=<uuid>\n");
703 exit(2);
704 }
Theodore Ts'oed1b33e2003-03-01 19:29:01 -0500705 dev = blkid_get_devname(NULL, argv[1], NULL);
Theodore Ts'o118d7da2002-08-17 23:01:22 -0400706 if (!dev) {
707 fprintf(stderr, "Filesystem matching %s not found\n",
708 argv[1]);
709 exit(1);
710 }
711 puts(dev);
712 exit(0);
713}
Theodore Ts'o83238152001-01-09 00:16:26 +0000714
715
716int main (int argc, char ** argv)
717{
718 errcode_t retval;
719 ext2_filsys fs;
720 struct ext2_super_block *sb;
Theodore Ts'o2a29f132003-05-05 12:08:47 -0400721 io_manager io_ptr;
Theodore Ts'o83238152001-01-09 00:16:26 +0000722
723#ifdef ENABLE_NLS
724 setlocale(LC_MESSAGES, "");
Theodore Ts'o14308a52002-03-05 03:26:52 -0500725 setlocale(LC_CTYPE, "");
Theodore Ts'o83238152001-01-09 00:16:26 +0000726 bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
727 textdomain(NLS_CAT_NAME);
728#endif
729 if (argc && *argv)
730 program_name = *argv;
731 initialize_ext2_error_table();
732
Theodore Ts'o118d7da2002-08-17 23:01:22 -0400733 if (strcmp(get_progname(argv[0]), "findfs") == 0)
734 do_findfs(argc, argv);
Theodore Ts'o83238152001-01-09 00:16:26 +0000735 if (strcmp(get_progname(argv[0]), "e2label") == 0)
736 parse_e2label_options(argc, argv);
737 else
738 parse_tune2fs_options(argc, argv);
739
Theodore Ts'o2a29f132003-05-05 12:08:47 -0400740#ifdef CONFIG_TESTIO_DEBUG
741 io_ptr = test_io_manager;
742 test_io_backing_manager = unix_io_manager;
743#else
744 io_ptr = unix_io_manager;
745#endif
746 retval = ext2fs_open (device_name, open_flag, 0, 0, io_ptr, &fs);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000747 if (retval) {
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000748 com_err (program_name, retval, _("while trying to open %s"),
Theodore Ts'o3839e651997-04-26 13:21:57 +0000749 device_name);
Theodore Ts'o7141b542001-08-15 19:17:37 -0400750 fprintf(stderr,
751 _("Couldn't find valid filesystem superblock.\n"));
Theodore Ts'o3839e651997-04-26 13:21:57 +0000752 exit(1);
753 }
Theodore Ts'o83238152001-01-09 00:16:26 +0000754 sb = fs->super;
755 if (print_label) {
756 /* For e2label emulation */
Theodore Ts'oc8c071a2001-01-11 16:08:23 +0000757 printf("%.*s\n", (int) sizeof(sb->s_volume_name),
758 sb->s_volume_name);
Theodore Ts'o83238152001-01-09 00:16:26 +0000759 exit(0);
760 }
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000761 retval = ext2fs_check_if_mounted(device_name, &mount_flags);
762 if (retval) {
763 com_err("ext2fs_check_if_mount", retval,
764 _("while determining whether %s is mounted."),
765 device_name);
Theodore Ts'o4055ef72001-01-14 16:11:14 +0000766 exit(1);
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000767 }
Theodore Ts'o63985322001-01-03 17:02:13 +0000768 /* Normally we only need to write out the superblock */
769 fs->flags |= EXT2_FLAG_SUPER_ONLY;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000770
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000771 if (c_flag) {
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000772 sb->s_max_mnt_count = max_mount_count;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000773 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000774 printf (_("Setting maximal mount count to %d\n"),
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000775 max_mount_count);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000776 }
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000777 if (C_flag) {
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000778 sb->s_mnt_count = mount_count;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000779 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000780 printf (_("Setting current mount count to %d\n"), mount_count);
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000781 }
782 if (e_flag) {
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000783 sb->s_errors = errors;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000784 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000785 printf (_("Setting error behavior to %d\n"), errors);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000786 }
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000787 if (g_flag) {
788 sb->s_def_resgid = resgid;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000789 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000790 printf (_("Setting reserved blocks gid to %lu\n"), resgid);
Theodore Ts'of3db3561997-04-26 13:34:30 +0000791 }
Theodore Ts'o818180c1998-06-27 05:11:14 +0000792 if (i_flag) {
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000793 sb->s_checkinterval = interval;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000794 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000795 printf (_("Setting interval between check %lu seconds\n"), interval);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000796 }
Theodore Ts'o818180c1998-06-27 05:11:14 +0000797 if (m_flag) {
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000798 sb->s_r_blocks_count = (sb->s_blocks_count / 100)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000799 * reserved_ratio;
800 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000801 printf (_("Setting reserved blocks percentage to %lu (%u blocks)\n"),
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000802 reserved_ratio, sb->s_r_blocks_count);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000803 }
Theodore Ts'o818180c1998-06-27 05:11:14 +0000804 if (r_flag) {
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000805 if (reserved_blocks >= sb->s_blocks_count) {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000806 com_err (program_name, 0,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000807 _("reserved blocks count is too big (%ul)"),
Theodore Ts'of3db3561997-04-26 13:34:30 +0000808 reserved_blocks);
809 exit (1);
810 }
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000811 sb->s_r_blocks_count = reserved_blocks;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000812 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000813 printf (_("Setting reserved blocks count to %lu\n"),
Theodore Ts'of3db3561997-04-26 13:34:30 +0000814 reserved_blocks);
815 }
Theodore Ts'o521e3681997-04-29 17:48:10 +0000816 if (s_flag == 1) {
Theodore Ts'o521e3681997-04-29 17:48:10 +0000817 if (sb->s_feature_ro_compat &
818 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000819 fprintf(stderr, _("\nThe filesystem already"
Theodore Ts'oe1a0a3e2000-02-11 05:00:19 +0000820 " has sparse superblocks.\n"));
Theodore Ts'o521e3681997-04-29 17:48:10 +0000821 else {
822 sb->s_feature_ro_compat |=
823 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000824 sb->s_state &= ~EXT2_VALID_FS;
Theodore Ts'o521e3681997-04-29 17:48:10 +0000825 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000826 printf(_("\nSparse superblock flag set. %s"),
Theodore Ts'oa4fa1002000-02-08 21:35:41 +0000827 _(please_fsck));
Theodore Ts'o521e3681997-04-29 17:48:10 +0000828 }
Theodore Ts'o521e3681997-04-29 17:48:10 +0000829 }
830 if (s_flag == 0) {
Theodore Ts'o521e3681997-04-29 17:48:10 +0000831 if (!(sb->s_feature_ro_compat &
832 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000833 fprintf(stderr, _("\nThe filesystem already"
Theodore Ts'oe1a0a3e2000-02-11 05:00:19 +0000834 " has sparse superblocks disabled.\n"));
Theodore Ts'o521e3681997-04-29 17:48:10 +0000835 else {
836 sb->s_feature_ro_compat &=
837 ~EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000838 sb->s_state &= ~EXT2_VALID_FS;
Theodore Ts'o521e3681997-04-29 17:48:10 +0000839 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
840 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000841 printf(_("\nSparse superblock flag cleared. %s"),
Theodore Ts'oa4fa1002000-02-08 21:35:41 +0000842 _(please_fsck));
Theodore Ts'o521e3681997-04-29 17:48:10 +0000843 }
Theodore Ts'o521e3681997-04-29 17:48:10 +0000844 }
Theodore Ts'od4de4aa2001-12-26 08:58:01 -0500845 if (T_flag) {
846 sb->s_lastcheck = last_check_time;
847 ext2fs_mark_super_dirty(fs);
848 printf(_("Setting time filesystem last checked to %s\n"),
849 ctime(&last_check_time));
850 }
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000851 if (u_flag) {
852 sb->s_def_resuid = resuid;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000853 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000854 printf (_("Setting reserved blocks uid to %lu\n"), resuid);
Theodore Ts'of3db3561997-04-26 13:34:30 +0000855 }
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000856 if (L_flag) {
Theodore Ts'oa789d841998-03-30 01:20:55 +0000857 if (strlen(new_label) > sizeof(sb->s_volume_name))
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000858 fprintf(stderr, _("Warning: label too "
859 "long, truncating.\n"));
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000860 memset(sb->s_volume_name, 0, sizeof(sb->s_volume_name));
861 strncpy(sb->s_volume_name, new_label,
862 sizeof(sb->s_volume_name));
863 ext2fs_mark_super_dirty(fs);
864 }
865 if (M_flag) {
866 memset(sb->s_last_mounted, 0, sizeof(sb->s_last_mounted));
867 strncpy(sb->s_last_mounted, new_last_mounted,
868 sizeof(sb->s_last_mounted));
869 ext2fs_mark_super_dirty(fs);
870 }
Theodore Ts'oa0c3fd52002-10-15 17:43:43 -0400871 if (mntopts_cmd)
872 update_mntopts(fs, mntopts_cmd);
Theodore Ts'o63985322001-01-03 17:02:13 +0000873 if (features_cmd)
874 update_feature_set(fs, features_cmd);
Theodore Ts'odc2ec522001-01-18 01:51:15 +0000875 if (journal_size || journal_device)
Theodore Ts'o63985322001-01-03 17:02:13 +0000876 add_journal(fs);
877
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000878 if (U_flag) {
Theodore Ts'o4d0f2282001-04-23 20:58:03 +0000879 if ((strcasecmp(new_UUID, "null") == 0) ||
880 (strcasecmp(new_UUID, "clear") == 0)) {
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000881 uuid_clear(sb->s_uuid);
Theodore Ts'o63985322001-01-03 17:02:13 +0000882 } else if (strcasecmp(new_UUID, "time") == 0) {
883 uuid_generate_time(sb->s_uuid);
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000884 } else if (strcasecmp(new_UUID, "random") == 0) {
885 uuid_generate(sb->s_uuid);
886 } else if (uuid_parse(new_UUID, sb->s_uuid)) {
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000887 com_err(program_name, 0, _("Invalid UUID format\n"));
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000888 exit(1);
889 }
890 ext2fs_mark_super_dirty(fs);
891 }
892
Theodore Ts'o3839e651997-04-26 13:21:57 +0000893 if (l_flag)
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000894 list_super (sb);
Andreas Dilgerc007bc02001-12-25 23:10:40 -0700895 return (ext2fs_close (fs) ? 1 : 0);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000896}