blob: 4a61a12a121e283d5243d7459ac99ba0f390a59e [file] [log] [blame]
Theodore Ts'o3839e651997-04-26 13:21:57 +00001/*
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 *
Theodore Ts'o19c78dc1997-04-29 16:17:09 +00009 * 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%
Theodore Ts'o3839e651997-04-26 13:21:57 +000015 */
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>
Theodore Ts'of3db3561997-04-26 13:34:30 +000030#include <grp.h>
Theodore Ts'oa418d3a1997-04-26 14:00:26 +000031#ifdef HAVE_GETOPT_H
Theodore Ts'o3839e651997-04-26 13:21:57 +000032#include <getopt.h>
Theodore Ts'o373b8332000-04-03 16:22:35 +000033#else
34extern char *optarg;
35extern int optind;
Theodore Ts'oa418d3a1997-04-26 14:00:26 +000036#endif
Theodore Ts'of3db3561997-04-26 13:34:30 +000037#include <pwd.h>
Theodore Ts'o3839e651997-04-26 13:21:57 +000038#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <time.h>
42#include <unistd.h>
Theodore Ts'of3db3561997-04-26 13:34:30 +000043#include <sys/types.h>
Theodore Ts'o3839e651997-04-26 13:21:57 +000044
45#include <linux/ext2_fs.h>
46
47#include "ext2fs/ext2fs.h"
48#include "et/com_err.h"
Theodore Ts'o1e3472c1997-04-29 14:53:37 +000049#include "uuid/uuid.h"
Theodore Ts'o3839e651997-04-26 13:21:57 +000050#include "e2p/e2p.h"
51
52#include "../version.h"
Theodore Ts'od9c56d32000-02-08 00:47:55 +000053#include "nls-enable.h"
Theodore Ts'o3839e651997-04-26 13:21:57 +000054
55const char * program_name = "tune2fs";
56char * device_name = NULL;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +000057char * new_label = NULL;
58char * new_last_mounted = NULL;
59char * new_UUID = NULL;
Theodore Ts'o3839e651997-04-26 13:21:57 +000060int c_flag = 0;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +000061int C_flag = 0;
Theodore Ts'o3839e651997-04-26 13:21:57 +000062int e_flag = 0;
Theodore Ts'of3db3561997-04-26 13:34:30 +000063int g_flag = 0;
Theodore Ts'o3839e651997-04-26 13:21:57 +000064int i_flag = 0;
65int l_flag = 0;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +000066int L_flag = 0;
Theodore Ts'o3839e651997-04-26 13:21:57 +000067int m_flag = 0;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +000068int M_flag = 0;
Theodore Ts'of3db3561997-04-26 13:34:30 +000069int r_flag = 0;
Theodore Ts'o521e3681997-04-29 17:48:10 +000070int s_flag = -1;
Theodore Ts'of3db3561997-04-26 13:34:30 +000071int u_flag = 0;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +000072int U_flag = 0;
73int max_mount_count, mount_count;
Theodore Ts'o3839e651997-04-26 13:21:57 +000074unsigned long interval;
75unsigned long reserved_ratio = 0;
Theodore Ts'of3db3561997-04-26 13:34:30 +000076unsigned long reserved_blocks = 0;
Theodore Ts'o3839e651997-04-26 13:21:57 +000077unsigned short errors;
Theodore Ts'of3db3561997-04-26 13:34:30 +000078unsigned long resgid = 0;
79unsigned long resuid = 0;
Theodore Ts'o3839e651997-04-26 13:21:57 +000080
Theodore Ts'o1e3472c1997-04-29 14:53:37 +000081#ifndef HAVE_STRCASECMP
82static int strcasecmp (char *s1, char *s2)
83{
84 while (*s1 && *s2) {
85 int ch1 = *s1++, ch2 = *s2++;
86 if (isupper (ch1))
87 ch1 = tolower (ch1);
88 if (isupper (ch2))
89 ch2 = tolower (ch2);
90 if (ch1 != ch2)
91 return ch1 - ch2;
92 }
93 return *s1 ? 1 : *s2 ? -1 : 0;
94}
95#endif
96
Theodore Ts'o818180c1998-06-27 05:11:14 +000097static void usage(void)
Theodore Ts'o3839e651997-04-26 13:21:57 +000098{
Theodore Ts'ob21e38a2001-01-01 15:26:58 +000099 fprintf(stderr,
100 _("Usage: %s [-c max-mounts-count] [-e errors-behavior] "
101 "[-g group]\n"
102 "\t[-i interval[d|m|w]] [-l] [-s sparse-flag] "
103 "[-m reserved-blocks-percent]\n"
104 "\t[-r reserved-blocks-count] [-u user] [-C mount-count]\n"
105 "\t[-L volume-label] [-M last-mounted-dir] [-U UUID]\n"
106 "\t[-O [^]feature[,...]] device\n"), program_name);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000107 exit (1);
108}
109
Theodore Ts'o896938d1999-10-23 01:04:50 +0000110static __u32 ok_features[3] = {
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000111 EXT3_FEATURE_COMPAT_HAS_JOURNAL, /* Compat */
Theodore Ts'o896938d1999-10-23 01:04:50 +0000112 EXT2_FEATURE_INCOMPAT_FILETYPE, /* Incompat */
113 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER /* R/O compat */
114};
115
Theodore Ts'oa4fa1002000-02-08 21:35:41 +0000116static const char *please_fsck = N_("Please run e2fsck on the filesystem.\n");
Theodore Ts'o896938d1999-10-23 01:04:50 +0000117
Theodore Ts'o00e54331997-09-16 02:13:52 +0000118int main (int argc, char ** argv)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000119{
Theodore Ts'o519149f1997-10-25 03:49:49 +0000120 int c;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000121 char * tmp;
122 errcode_t retval;
123 ext2_filsys fs;
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000124 struct ext2_super_block *sb;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000125 struct group * gr;
126 struct passwd * pw;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000127 int open_flag = 0;
Theodore Ts'o896938d1999-10-23 01:04:50 +0000128 char *features_cmd = 0;
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000129 int mount_flags = 0;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000130
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000131#ifdef ENABLE_NLS
132 setlocale(LC_MESSAGES, "");
133 bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
134 textdomain(NLS_CAT_NAME);
135#endif
136 fprintf (stderr, _("tune2fs %s, %s for EXT2 FS %s, %s\n"),
Theodore Ts'o3839e651997-04-26 13:21:57 +0000137 E2FSPROGS_VERSION, E2FSPROGS_DATE,
138 EXT2FS_VERSION, EXT2FS_DATE);
139 if (argc && *argv)
140 program_name = *argv;
141 initialize_ext2_error_table();
Theodore Ts'o896938d1999-10-23 01:04:50 +0000142 while ((c = getopt (argc, argv, "c:e:g:i:lm:r:s:u:C:L:M:O:U:")) != EOF)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000143 switch (c)
144 {
145 case 'c':
Theodore Ts'o45d9e2f2000-07-07 03:12:54 +0000146 max_mount_count = strtol (optarg, &tmp, 0);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000147 if (*tmp || max_mount_count > 16000) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000148 com_err (program_name, 0,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000149 _("bad mounts count - %s"),
Theodore Ts'o3839e651997-04-26 13:21:57 +0000150 optarg);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000151 usage();
Theodore Ts'o3839e651997-04-26 13:21:57 +0000152 }
153 c_flag = 1;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000154 open_flag = EXT2_FLAG_RW;
155 break;
156 case 'C':
157 mount_count = strtoul (optarg, &tmp, 0);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000158 if (*tmp || mount_count > 16000) {
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000159 com_err (program_name, 0,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000160 _("bad mounts count - %s"),
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000161 optarg);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000162 usage();
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000163 }
164 C_flag = 1;
165 open_flag = EXT2_FLAG_RW;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000166 break;
167 case 'e':
168 if (strcmp (optarg, "continue") == 0)
169 errors = EXT2_ERRORS_CONTINUE;
170 else if (strcmp (optarg, "remount-ro") == 0)
171 errors = EXT2_ERRORS_RO;
172 else if (strcmp (optarg, "panic") == 0)
173 errors = EXT2_ERRORS_PANIC;
Theodore Ts'o818180c1998-06-27 05:11:14 +0000174 else {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000175 com_err (program_name, 0,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000176 _("bad error behavior - %s"),
Theodore Ts'o3839e651997-04-26 13:21:57 +0000177 optarg);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000178 usage();
Theodore Ts'o3839e651997-04-26 13:21:57 +0000179 }
180 e_flag = 1;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000181 open_flag = EXT2_FLAG_RW;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000182 break;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000183 case 'g':
184 resgid = strtoul (optarg, &tmp, 0);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000185 if (*tmp) {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000186 gr = getgrnam (optarg);
187 if (gr == NULL)
188 tmp = optarg;
Theodore Ts'oa418d3a1997-04-26 14:00:26 +0000189 else {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000190 resgid = gr->gr_gid;
Theodore Ts'oa418d3a1997-04-26 14:00:26 +0000191 *tmp =0;
192 }
Theodore Ts'of3db3561997-04-26 13:34:30 +0000193 }
Theodore Ts'o818180c1998-06-27 05:11:14 +0000194 if (*tmp) {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000195 com_err (program_name, 0,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000196 _("bad gid/group name - %s"),
Theodore Ts'of3db3561997-04-26 13:34:30 +0000197 optarg);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000198 usage();
Theodore Ts'of3db3561997-04-26 13:34:30 +0000199 }
200 g_flag = 1;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000201 open_flag = EXT2_FLAG_RW;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000202 break;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000203 case 'i':
204 interval = strtoul (optarg, &tmp, 0);
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000205 switch (*tmp) {
206 case 's':
207 tmp++;
208 break;
209 case '\0':
210 case 'd':
211 case 'D': /* days */
212 interval *= 86400;
213 if (*tmp != '\0')
Theodore Ts'o3839e651997-04-26 13:21:57 +0000214 tmp++;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000215 break;
216 case 'm':
217 case 'M': /* months! */
218 interval *= 86400 * 30;
219 tmp++;
220 break;
221 case 'w':
222 case 'W': /* weeks */
223 interval *= 86400 * 7;
224 tmp++;
225 break;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000226 }
Theodore Ts'o818180c1998-06-27 05:11:14 +0000227 if (*tmp || interval > (365 * 86400)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000228 com_err (program_name, 0,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000229 _("bad interval - %s"), optarg);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000230 usage();
Theodore Ts'o3839e651997-04-26 13:21:57 +0000231 }
232 i_flag = 1;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000233 open_flag = EXT2_FLAG_RW;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000234 break;
235 case 'l':
236 l_flag = 1;
237 break;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000238 case 'L':
239 new_label = optarg;
240 L_flag = 1;
241 open_flag = EXT2_FLAG_RW;
242 break;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000243 case 'm':
244 reserved_ratio = strtoul (optarg, &tmp, 0);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000245 if (*tmp || reserved_ratio > 50) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000246 com_err (program_name, 0,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000247 _("bad reserved block ratio - %s"),
Theodore Ts'o3839e651997-04-26 13:21:57 +0000248 optarg);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000249 usage();
Theodore Ts'o3839e651997-04-26 13:21:57 +0000250 }
251 m_flag = 1;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000252 open_flag = EXT2_FLAG_RW;
253 break;
254 case 'M':
255 new_last_mounted = optarg;
256 M_flag = 1;
257 open_flag = EXT2_FLAG_RW;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000258 break;
Theodore Ts'o896938d1999-10-23 01:04:50 +0000259 case 'O':
260 features_cmd = optarg;
261 open_flag = EXT2_FLAG_RW;
262 break;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000263 case 'r':
264 reserved_blocks = strtoul (optarg, &tmp, 0);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000265 if (*tmp) {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000266 com_err (program_name, 0,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000267 _("bad reserved blocks count - %s"),
Theodore Ts'of3db3561997-04-26 13:34:30 +0000268 optarg);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000269 usage();
Theodore Ts'of3db3561997-04-26 13:34:30 +0000270 }
271 r_flag = 1;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000272 open_flag = EXT2_FLAG_RW;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000273 break;
Theodore Ts'o521e3681997-04-29 17:48:10 +0000274 case 's':
275 s_flag = atoi(optarg);
276 open_flag = EXT2_FLAG_RW;
277 break;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000278 case 'u':
279 resuid = strtoul (optarg, &tmp, 0);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000280 if (*tmp) {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000281 pw = getpwnam (optarg);
282 if (pw == NULL)
283 tmp = optarg;
Theodore Ts'oa418d3a1997-04-26 14:00:26 +0000284 else {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000285 resuid = pw->pw_uid;
Theodore Ts'oa418d3a1997-04-26 14:00:26 +0000286 *tmp = 0;
287 }
Theodore Ts'of3db3561997-04-26 13:34:30 +0000288 }
Theodore Ts'o818180c1998-06-27 05:11:14 +0000289 if (*tmp) {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000290 com_err (program_name, 0,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000291 _("bad uid/user name - %s"),
Theodore Ts'of3db3561997-04-26 13:34:30 +0000292 optarg);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000293 usage();
Theodore Ts'of3db3561997-04-26 13:34:30 +0000294 }
295 u_flag = 1;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000296 open_flag = EXT2_FLAG_RW;
297 break;
298 case 'U':
299 new_UUID = optarg;
300 U_flag = 1;
301 open_flag = EXT2_FLAG_RW;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000302 break;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000303 default:
Theodore Ts'o818180c1998-06-27 05:11:14 +0000304 usage();
Theodore Ts'o3839e651997-04-26 13:21:57 +0000305 }
306 if (optind < argc - 1 || optind == argc)
Theodore Ts'o818180c1998-06-27 05:11:14 +0000307 usage();
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000308 if (!open_flag && !l_flag)
309 usage();
Theodore Ts'o3839e651997-04-26 13:21:57 +0000310 device_name = argv[optind];
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000311 retval = ext2fs_open (device_name, open_flag, 0, 0,
312 unix_io_manager, &fs);
Theodore Ts'o818180c1998-06-27 05:11:14 +0000313 if (retval) {
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000314 com_err (program_name, retval, _("while trying to open %s"),
Theodore Ts'o3839e651997-04-26 13:21:57 +0000315 device_name);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000316 printf(_("Couldn't find valid filesystem superblock.\n"));
Theodore Ts'o3839e651997-04-26 13:21:57 +0000317 exit(1);
318 }
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000319 retval = ext2fs_check_if_mounted(device_name, &mount_flags);
320 if (retval) {
321 com_err("ext2fs_check_if_mount", retval,
322 _("while determining whether %s is mounted."),
323 device_name);
324 return;
325 }
326 sb = fs->super;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000327
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000328 if (c_flag) {
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000329 sb->s_max_mnt_count = max_mount_count;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000330 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000331 printf (_("Setting maximal mount count to %d\n"),
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000332 max_mount_count);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000333 }
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000334 if (C_flag) {
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000335 sb->s_mnt_count = mount_count;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000336 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000337 printf (_("Setting current mount count to %d\n"), mount_count);
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000338 }
339 if (e_flag) {
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000340 sb->s_errors = errors;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000341 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000342 printf (_("Setting error behavior to %d\n"), errors);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000343 }
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000344 if (g_flag) {
345 sb->s_def_resgid = resgid;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000346 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000347 printf (_("Setting reserved blocks gid to %lu\n"), resgid);
Theodore Ts'of3db3561997-04-26 13:34:30 +0000348 }
Theodore Ts'o818180c1998-06-27 05:11:14 +0000349 if (i_flag) {
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000350 sb->s_checkinterval = interval;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000351 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000352 printf (_("Setting interval between check %lu seconds\n"), interval);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000353 }
Theodore Ts'o818180c1998-06-27 05:11:14 +0000354 if (m_flag) {
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000355 sb->s_r_blocks_count = (sb->s_blocks_count / 100)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000356 * reserved_ratio;
357 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000358 printf (_("Setting reserved blocks percentage to %lu (%u blocks)\n"),
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000359 reserved_ratio, sb->s_r_blocks_count);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000360 }
Theodore Ts'o818180c1998-06-27 05:11:14 +0000361 if (r_flag) {
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000362 if (reserved_blocks >= sb->s_blocks_count) {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000363 com_err (program_name, 0,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000364 _("reserved blocks count is too big (%ul)"),
Theodore Ts'of3db3561997-04-26 13:34:30 +0000365 reserved_blocks);
366 exit (1);
367 }
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000368 sb->s_r_blocks_count = reserved_blocks;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000369 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000370 printf (_("Setting reserved blocks count to %lu\n"),
Theodore Ts'of3db3561997-04-26 13:34:30 +0000371 reserved_blocks);
372 }
Theodore Ts'o521e3681997-04-29 17:48:10 +0000373 if (s_flag == 1) {
Theodore Ts'o521e3681997-04-29 17:48:10 +0000374 if (sb->s_feature_ro_compat &
375 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000376 fprintf(stderr, _("\nThe filesystem already"
Theodore Ts'oe1a0a3e2000-02-11 05:00:19 +0000377 " has sparse superblocks.\n"));
Theodore Ts'o521e3681997-04-29 17:48:10 +0000378 else {
379 sb->s_feature_ro_compat |=
380 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000381 sb->s_state &= ~EXT2_VALID_FS;
Theodore Ts'o521e3681997-04-29 17:48:10 +0000382 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000383 printf(_("\nSparse superblock flag set. %s"),
Theodore Ts'oa4fa1002000-02-08 21:35:41 +0000384 _(please_fsck));
Theodore Ts'o521e3681997-04-29 17:48:10 +0000385 }
Theodore Ts'o521e3681997-04-29 17:48:10 +0000386 }
387 if (s_flag == 0) {
Theodore Ts'o521e3681997-04-29 17:48:10 +0000388 if (!(sb->s_feature_ro_compat &
389 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000390 fprintf(stderr, _("\nThe filesystem already"
Theodore Ts'oe1a0a3e2000-02-11 05:00:19 +0000391 " has sparse superblocks disabled.\n"));
Theodore Ts'o521e3681997-04-29 17:48:10 +0000392 else {
393 sb->s_feature_ro_compat &=
394 ~EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000395 sb->s_state &= ~EXT2_VALID_FS;
Theodore Ts'o521e3681997-04-29 17:48:10 +0000396 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
397 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000398 printf(_("\nSparse superblock flag cleared. %s"),
Theodore Ts'oa4fa1002000-02-08 21:35:41 +0000399 _(please_fsck));
Theodore Ts'o521e3681997-04-29 17:48:10 +0000400 }
Theodore Ts'o521e3681997-04-29 17:48:10 +0000401 }
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000402 if (u_flag) {
403 sb->s_def_resuid = resuid;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000404 ext2fs_mark_super_dirty(fs);
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000405 printf (_("Setting reserved blocks uid to %lu\n"), resuid);
Theodore Ts'of3db3561997-04-26 13:34:30 +0000406 }
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000407 if (L_flag) {
Theodore Ts'oa789d841998-03-30 01:20:55 +0000408 if (strlen(new_label) > sizeof(sb->s_volume_name))
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000409 fprintf(stderr, _("Warning: label too "
410 "long, truncating.\n"));
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000411 memset(sb->s_volume_name, 0, sizeof(sb->s_volume_name));
412 strncpy(sb->s_volume_name, new_label,
413 sizeof(sb->s_volume_name));
414 ext2fs_mark_super_dirty(fs);
415 }
416 if (M_flag) {
417 memset(sb->s_last_mounted, 0, sizeof(sb->s_last_mounted));
418 strncpy(sb->s_last_mounted, new_last_mounted,
419 sizeof(sb->s_last_mounted));
420 ext2fs_mark_super_dirty(fs);
421 }
Theodore Ts'o896938d1999-10-23 01:04:50 +0000422 if (features_cmd) {
423 int sparse, old_sparse, filetype, old_filetype;
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000424 int journal, old_journal;
Theodore Ts'o896938d1999-10-23 01:04:50 +0000425
426 old_sparse = sb->s_feature_ro_compat &
427 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
428 old_filetype = sb->s_feature_incompat &
429 EXT2_FEATURE_INCOMPAT_FILETYPE;
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000430 old_journal = sb->s_feature_compat &
431 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
Theodore Ts'o896938d1999-10-23 01:04:50 +0000432 if (e2p_edit_feature(features_cmd,
433 &sb->s_feature_compat,
434 ok_features)) {
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000435 fprintf(stderr, _("Invalid filesystem option set: %s\n"),
Theodore Ts'o896938d1999-10-23 01:04:50 +0000436 features_cmd);
437 exit(1);
438 }
439 sparse = sb->s_feature_ro_compat &
440 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
441 filetype = sb->s_feature_incompat &
442 EXT2_FEATURE_INCOMPAT_FILETYPE;
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000443 journal = sb->s_feature_compat &
444 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
445 if (old_journal && !journal &&
446 (mount_flags & EXT2_MF_MOUNTED) &&
447 !(mount_flags & EXT2_MF_READONLY)) {
448 fprintf(stderr,
449 _("The HAS_JOURNAL flag may only be cleared "
450 "the filesystem is unmounted\n"
451 "or mounted read-only.\n"));
452 exit(1);
453 }
Theodore Ts'o896938d1999-10-23 01:04:50 +0000454 if ((sparse != old_sparse) ||
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000455 (filetype != old_filetype) ||
456 (journal != old_journal)) {
457 sb->s_state &= ~EXT2_VALID_FS;
Theodore Ts'oa4fa1002000-02-08 21:35:41 +0000458 printf("\n%s\n", _(please_fsck));
Theodore Ts'o896938d1999-10-23 01:04:50 +0000459 }
460 ext2fs_mark_super_dirty(fs);
461 }
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000462 if (U_flag) {
463 if (strcasecmp(new_UUID, "null") == 0) {
464 uuid_clear(sb->s_uuid);
465 } else if (strcasecmp(new_UUID, "random") == 0) {
466 uuid_generate(sb->s_uuid);
467 } else if (uuid_parse(new_UUID, sb->s_uuid)) {
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000468 com_err(program_name, 0, _("Invalid UUID format\n"));
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000469 exit(1);
470 }
471 ext2fs_mark_super_dirty(fs);
472 }
473
Theodore Ts'o3839e651997-04-26 13:21:57 +0000474 if (l_flag)
Theodore Ts'ob21e38a2001-01-01 15:26:58 +0000475 list_super (sb);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000476 ext2fs_close (fs);
477 exit (0);
478}