2 * tune2fs.c - Change the file system parameters on
3 * an unmounted second extended file system
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)
9 * Copyright 1995, 1996, 1997 by Theodore Ts'o.
12 * This file may be redistributed under the terms of the GNU Public
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)
43 #include <sys/types.h>
45 #include <linux/ext2_fs.h>
47 #include "ext2fs/ext2fs.h"
48 #include "et/com_err.h"
49 #include "uuid/uuid.h"
52 #include "../version.h"
53 #include "nls-enable.h"
55 const char * program_name
= "tune2fs";
56 char * device_name
= NULL
;
57 char * new_label
= NULL
;
58 char * new_last_mounted
= NULL
;
59 char * new_UUID
= NULL
;
73 int max_mount_count
, mount_count
;
74 unsigned long interval
;
75 unsigned long reserved_ratio
= 0;
76 unsigned long reserved_blocks
= 0;
77 unsigned short errors
;
78 unsigned long resgid
= 0;
79 unsigned long resuid
= 0;
81 #ifndef HAVE_STRCASECMP
82 static int strcasecmp (char *s1
, char *s2
)
85 int ch1
= *s1
++, ch2
= *s2
++;
93 return *s1
? 1 : *s2
? -1 : 0;
97 static void usage(void)
99 fprintf(stderr
, _("Usage: %s [-c max-mounts-count] [-e errors-behavior] "
101 "\t[-i interval[d|m|w]] [-l] [-s sparse-flag] "
102 "[-m reserved-blocks-percent]\n"
103 "\t[-r reserved-blocks-count] [-u user] [-C mount-count]\n"
104 "\t[-L volume-label] [-M last-mounted-dir] [-U UUID]\n"
105 "\t[-O [^]feature[,...]] device\n"), program_name
);
109 static __u32 ok_features
[3] = {
111 EXT2_FEATURE_INCOMPAT_FILETYPE
, /* Incompat */
112 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
/* R/O compat */
115 static const char *please_fsck
= N_("Please run e2fsck on the filesystem.\n");
117 int main (int argc
, char ** argv
)
123 struct ext2fs_sb
*sb
;
127 char *features_cmd
= 0;
130 setlocale(LC_MESSAGES
, "");
131 bindtextdomain(NLS_CAT_NAME
, LOCALEDIR
);
132 textdomain(NLS_CAT_NAME
);
134 fprintf (stderr
, _("tune2fs %s, %s for EXT2 FS %s, %s\n"),
135 E2FSPROGS_VERSION
, E2FSPROGS_DATE
,
136 EXT2FS_VERSION
, EXT2FS_DATE
);
138 program_name
= *argv
;
139 initialize_ext2_error_table();
140 while ((c
= getopt (argc
, argv
, "c:e:g:i:lm:r:s:u:C:L:M:O:U:")) != EOF
)
144 max_mount_count
= strtoul (optarg
, &tmp
, 0);
145 if (*tmp
|| max_mount_count
> 16000) {
146 com_err (program_name
, 0,
147 _("bad mounts count - %s"),
152 open_flag
= EXT2_FLAG_RW
;
155 mount_count
= strtoul (optarg
, &tmp
, 0);
156 if (*tmp
|| mount_count
> 16000) {
157 com_err (program_name
, 0,
158 _("bad mounts count - %s"),
163 open_flag
= EXT2_FLAG_RW
;
166 if (strcmp (optarg
, "continue") == 0)
167 errors
= EXT2_ERRORS_CONTINUE
;
168 else if (strcmp (optarg
, "remount-ro") == 0)
169 errors
= EXT2_ERRORS_RO
;
170 else if (strcmp (optarg
, "panic") == 0)
171 errors
= EXT2_ERRORS_PANIC
;
173 com_err (program_name
, 0,
174 _("bad error behavior - %s"),
179 open_flag
= EXT2_FLAG_RW
;
182 resgid
= strtoul (optarg
, &tmp
, 0);
184 gr
= getgrnam (optarg
);
193 com_err (program_name
, 0,
194 _("bad gid/group name - %s"),
199 open_flag
= EXT2_FLAG_RW
;
202 interval
= strtoul (optarg
, &tmp
, 0);
215 case 'M': /* months! */
216 interval
*= 86400 * 30;
220 case 'W': /* weeks */
221 interval
*= 86400 * 7;
225 if (*tmp
|| interval
> (365 * 86400)) {
226 com_err (program_name
, 0,
227 _("bad interval - %s"), optarg
);
231 open_flag
= EXT2_FLAG_RW
;
239 open_flag
= EXT2_FLAG_RW
;
242 reserved_ratio
= strtoul (optarg
, &tmp
, 0);
243 if (*tmp
|| reserved_ratio
> 50) {
244 com_err (program_name
, 0,
245 _("bad reserved block ratio - %s"),
250 open_flag
= EXT2_FLAG_RW
;
253 new_last_mounted
= optarg
;
255 open_flag
= EXT2_FLAG_RW
;
258 features_cmd
= optarg
;
259 open_flag
= EXT2_FLAG_RW
;
262 reserved_blocks
= strtoul (optarg
, &tmp
, 0);
264 com_err (program_name
, 0,
265 _("bad reserved blocks count - %s"),
270 open_flag
= EXT2_FLAG_RW
;
273 s_flag
= atoi(optarg
);
274 open_flag
= EXT2_FLAG_RW
;
277 resuid
= strtoul (optarg
, &tmp
, 0);
279 pw
= getpwnam (optarg
);
288 com_err (program_name
, 0,
289 _("bad uid/user name - %s"),
294 open_flag
= EXT2_FLAG_RW
;
299 open_flag
= EXT2_FLAG_RW
;
304 if (optind
< argc
- 1 || optind
== argc
)
306 if (!open_flag
&& !l_flag
)
308 device_name
= argv
[optind
];
309 retval
= ext2fs_open (device_name
, open_flag
, 0, 0,
310 unix_io_manager
, &fs
);
312 com_err (program_name
, retval
, _("while trying to open %s"),
314 printf(_("Couldn't find valid filesystem superblock.\n"));
317 sb
= (struct ext2fs_sb
*) fs
->super
;
320 fs
->super
->s_max_mnt_count
= max_mount_count
;
321 ext2fs_mark_super_dirty(fs
);
322 printf (_("Setting maximal mount count to %d\n"),
326 fs
->super
->s_mnt_count
= mount_count
;
327 ext2fs_mark_super_dirty(fs
);
328 printf (_("Setting current mount count to %d\n"), mount_count
);
331 fs
->super
->s_errors
= errors
;
332 ext2fs_mark_super_dirty(fs
);
333 printf (_("Setting error behavior to %d\n"), errors
);
336 #ifdef EXT2_DEF_RESGID
338 fs
->super
->s_def_resgid
= resgid
;
339 ext2fs_mark_super_dirty(fs
);
340 printf (_("Setting reserved blocks gid to %lu\n"), resgid
);
343 com_err (program_name
, 0,
344 _("The -g option is not supported by this version -- "
345 "Recompile with a newer kernel"));
348 fs
->super
->s_checkinterval
= interval
;
349 ext2fs_mark_super_dirty(fs
);
350 printf (_("Setting interval between check %lu seconds\n"), interval
);
353 fs
->super
->s_r_blocks_count
= (fs
->super
->s_blocks_count
/ 100)
355 ext2fs_mark_super_dirty(fs
);
356 printf (_("Setting reserved blocks percentage to %lu (%u blocks)\n"),
357 reserved_ratio
, fs
->super
->s_r_blocks_count
);
360 if (reserved_blocks
>= fs
->super
->s_blocks_count
) {
361 com_err (program_name
, 0,
362 _("reserved blocks count is too big (%ul)"),
366 fs
->super
->s_r_blocks_count
= reserved_blocks
;
367 ext2fs_mark_super_dirty(fs
);
368 printf (_("Setting reserved blocks count to %lu\n"),
372 #ifdef EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
373 if (sb
->s_feature_ro_compat
&
374 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
)
375 fprintf(stderr
, _("\nThe filesystem already"
376 " has sparse superblocks.\n"));
378 sb
->s_feature_ro_compat
|=
379 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
;
380 fs
->super
->s_state
&= ~EXT2_VALID_FS
;
381 ext2fs_mark_super_dirty(fs
);
382 printf(_("\nSparse superblock flag set. %s"),
385 #else /* !EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER */
386 com_err (program_name
, 0,
387 _("The -s option is not supported by this version -- "
388 "Recompile with a newer kernel"));
389 #endif /* EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER */
392 #ifdef EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
393 if (!(sb
->s_feature_ro_compat
&
394 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
))
395 fprintf(stderr
, _("\nThe filesystem already"
396 " has sparse superblocks disabled.\n"));
398 sb
->s_feature_ro_compat
&=
399 ~EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
;
400 fs
->super
->s_state
&= ~EXT2_VALID_FS
;
401 fs
->flags
|= EXT2_FLAG_MASTER_SB_ONLY
;
402 ext2fs_mark_super_dirty(fs
);
403 printf(_("\nSparse superblock flag cleared. %s"),
406 #else /* !EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER */
407 com_err (program_name
, 0,
408 _("The -s option is not supported by this version -- "
409 "Recompile with a newer kernel"));
410 #endif /* EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER */
414 #ifdef EXT2_DEF_RESUID
416 fs
->super
->s_def_resuid
= resuid
;
417 ext2fs_mark_super_dirty(fs
);
418 printf (_("Setting reserved blocks uid to %lu\n"), resuid
);
421 com_err (program_name
, 0,
422 _("The -u option is not supported by this version -- "
423 "Recompile with a newer kernel"));
426 if (strlen(new_label
) > sizeof(sb
->s_volume_name
))
427 fprintf(stderr
, _("Warning: label too "
428 "long, truncating.\n"));
429 memset(sb
->s_volume_name
, 0, sizeof(sb
->s_volume_name
));
430 strncpy(sb
->s_volume_name
, new_label
,
431 sizeof(sb
->s_volume_name
));
432 ext2fs_mark_super_dirty(fs
);
435 memset(sb
->s_last_mounted
, 0, sizeof(sb
->s_last_mounted
));
436 strncpy(sb
->s_last_mounted
, new_last_mounted
,
437 sizeof(sb
->s_last_mounted
));
438 ext2fs_mark_super_dirty(fs
);
441 int sparse
, old_sparse
, filetype
, old_filetype
;
443 old_sparse
= sb
->s_feature_ro_compat
&
444 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
;
445 old_filetype
= sb
->s_feature_incompat
&
446 EXT2_FEATURE_INCOMPAT_FILETYPE
;
447 if (e2p_edit_feature(features_cmd
,
448 &sb
->s_feature_compat
,
450 fprintf(stderr
, _("Invalid filesystem option set: %s\n"),
454 sparse
= sb
->s_feature_ro_compat
&
455 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
;
456 filetype
= sb
->s_feature_incompat
&
457 EXT2_FEATURE_INCOMPAT_FILETYPE
;
458 if ((sparse
!= old_sparse
) ||
459 (filetype
!= old_filetype
)) {
460 fs
->super
->s_state
&= ~EXT2_VALID_FS
;
461 printf("\n%s\n", _(please_fsck
));
463 ext2fs_mark_super_dirty(fs
);
466 if (strcasecmp(new_UUID
, "null") == 0) {
467 uuid_clear(sb
->s_uuid
);
468 } else if (strcasecmp(new_UUID
, "random") == 0) {
469 uuid_generate(sb
->s_uuid
);
470 } else if (uuid_parse(new_UUID
, sb
->s_uuid
)) {
471 com_err(program_name
, 0, _("Invalid UUID format\n"));
474 ext2fs_mark_super_dirty(fs
);
478 list_super (fs
->super
);