aboutsummaryrefslogtreecommitdiff
path: root/e2fsprogs/tune2fs.c
diff options
context:
space:
mode:
Diffstat (limited to 'e2fsprogs/tune2fs.c')
-rw-r--r--e2fsprogs/tune2fs.c183
1 files changed, 68 insertions, 115 deletions
diff --git a/e2fsprogs/tune2fs.c b/e2fsprogs/tune2fs.c
index b78b0139d..ccbbc7868 100644
--- a/e2fsprogs/tune2fs.c
+++ b/e2fsprogs/tune2fs.c
@@ -50,7 +50,7 @@ extern int optind;
50#include "util.h" 50#include "util.h"
51#include "blkid/blkid.h" 51#include "blkid/blkid.h"
52 52
53static char * device_name; 53static char * device_name = NULL;
54static char * new_label, *new_last_mounted, *new_UUID; 54static char * new_label, *new_last_mounted, *new_UUID;
55static char * io_options; 55static char * io_options;
56static int c_flag, C_flag, e_flag, f_flag, g_flag, i_flag, l_flag, L_flag; 56static int c_flag, C_flag, e_flag, f_flag, g_flag, i_flag, l_flag, L_flag;
@@ -66,7 +66,7 @@ static char *features_cmd;
66static char *mntopts_cmd; 66static char *mntopts_cmd;
67 67
68static int journal_size, journal_flags; 68static int journal_size, journal_flags;
69static char *journal_device; 69static char *journal_device = NULL;
70 70
71static const char *please_fsck = "Please run e2fsck on the filesystem\n"; 71static const char *please_fsck = "Please run e2fsck on the filesystem\n";
72 72
@@ -188,26 +188,36 @@ static void remove_journal_inode(ext2_filsys fs)
188 struct ext2_inode inode; 188 struct ext2_inode inode;
189 errcode_t retval; 189 errcode_t retval;
190 ino_t ino = fs->super->s_journal_inum; 190 ino_t ino = fs->super->s_journal_inum;
191 char *msg = "to read";
192 char *s = "journal inode";
191 193
192 retval = ext2fs_read_inode(fs, ino, &inode); 194 retval = ext2fs_read_inode(fs, ino, &inode);
193 if (retval) 195 if (retval)
194 bb_error_msg_and_die("Failed to read journal inode"); 196 goto REMOVE_JOURNAL_INODE_ERROR;
195 if (ino == EXT2_JOURNAL_INO) { 197 if (ino == EXT2_JOURNAL_INO) {
196 retval = ext2fs_read_bitmaps(fs); 198 retval = ext2fs_read_bitmaps(fs);
197 if (retval) 199 if (retval) {
198 bb_error_msg_and_die("Failed to read bitmaps"); 200 msg = "to read bitmaps";
201 s = "";
202 goto REMOVE_JOURNAL_INODE_ERROR;
203 }
199 retval = ext2fs_block_iterate(fs, ino, 0, NULL, 204 retval = ext2fs_block_iterate(fs, ino, 0, NULL,
200 release_blocks_proc, NULL); 205 release_blocks_proc, NULL);
201 if (retval) 206 if (retval) {
202 bb_error_msg_and_die("Failed clearing journal inode"); 207 msg = "clearing";
208 goto REMOVE_JOURNAL_INODE_ERROR;
209 }
203 memset(&inode, 0, sizeof(inode)); 210 memset(&inode, 0, sizeof(inode));
204 ext2fs_mark_bb_dirty(fs); 211 ext2fs_mark_bb_dirty(fs);
205 fs->flags &= ~EXT2_FLAG_SUPER_ONLY; 212 fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
206 } else 213 } else
207 inode.i_flags &= ~EXT2_IMMUTABLE_FL; 214 inode.i_flags &= ~EXT2_IMMUTABLE_FL;
208 retval = ext2fs_write_inode(fs, ino, &inode); 215 retval = ext2fs_write_inode(fs, ino, &inode);
209 if (retval) 216 if (retval) {
210 bb_error_msg_and_die("Failed writing journal inode"); 217 msg = "writing";
218REMOVE_JOURNAL_INODE_ERROR:
219 bb_error_msg_and_die("Failed %s %s", msg, s);
220 }
211 fs->super->s_journal_inum = 0; 221 fs->super->s_journal_inum = 0;
212 ext2fs_mark_super_dirty(fs); 222 ext2fs_mark_super_dirty(fs);
213} 223}
@@ -269,8 +279,8 @@ static void update_feature_set(ext2_filsys fs, char *features)
269 EXT3_FEATURE_INCOMPAT_RECOVER) { 279 EXT3_FEATURE_INCOMPAT_RECOVER) {
270 bb_error_msg_and_die( 280 bb_error_msg_and_die(
271 "The needs_recovery flag is set. " 281 "The needs_recovery flag is set. "
272 "Please run e2fsck before clearing\n" 282 "%s before clearing the has_journal flag.",
273 "the has_journal flag."); 283 please_fsck);
274 } 284 }
275 if (sb->s_journal_inum) { 285 if (sb->s_journal_inum) {
276 remove_journal_inode(fs); 286 remove_journal_inode(fs);
@@ -317,48 +327,14 @@ static void update_feature_set(ext2_filsys fs, char *features)
317 */ 327 */
318static void add_journal(ext2_filsys fs) 328static void add_journal(ext2_filsys fs)
319{ 329{
320 unsigned long journal_blocks;
321 errcode_t retval;
322 ext2_filsys jfs;
323 io_manager io_ptr;
324
325 if (fs->super->s_feature_compat & 330 if (fs->super->s_feature_compat &
326 EXT3_FEATURE_COMPAT_HAS_JOURNAL) { 331 EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
327 bb_error_msg("The filesystem already has a journal"); 332 bb_error_msg_and_die("The filesystem already has a journal");
328 goto err;
329 } 333 }
330 if (journal_device) { 334 if (journal_device) {
331 check_plausibility(journal_device); 335 make_journal_device(journal_device, fs, 0, 0);
332 check_mount(journal_device, 0, "journal");
333 io_ptr = unix_io_manager;
334 retval = ext2fs_open(journal_device, EXT2_FLAG_RW|
335 EXT2_FLAG_JOURNAL_DEV_OK, 0,
336 fs->blocksize, io_ptr, &jfs);
337 if (retval) {
338 bb_error_msg("Failed to open journal on %s", journal_device);
339 goto err;
340 }
341 printf("Creating journal on device %s: ", journal_device);
342 fflush(stdout);
343
344 retval = ext2fs_add_journal_device(fs, jfs);
345 ext2fs_close(jfs);
346 if (retval) {
347 bb_error_msg("Failed to add filesystem to journal on %s", journal_device);
348 goto err;
349 }
350 puts("done");
351 } else if (journal_size) { 336 } else if (journal_size) {
352 fputs("Creating journal inode: ", stdout); 337 make_journal_blocks(fs, journal_size, journal_flags, 0);
353 fflush(stdout);
354 journal_blocks = figure_journal_size(journal_size, fs);
355
356 retval = ext2fs_add_journal_inode(fs, journal_blocks,
357 journal_flags);
358 if (retval)
359 bb_error_msg_and_die("Failed to create journal file");
360 else
361 puts("done");
362 /* 338 /*
363 * If the filesystem wasn't mounted, we need to force 339 * If the filesystem wasn't mounted, we need to force
364 * the block group descriptors out. 340 * the block group descriptors out.
@@ -368,11 +344,18 @@ static void add_journal(ext2_filsys fs)
368 } 344 }
369 print_check_message(fs); 345 print_check_message(fs);
370 return; 346 return;
347}
371 348
372err: 349/*
373 if (journal_device) 350 * Busybox stuff
374 free(journal_device); 351 */
375 exit(1); 352static char * x_blkid_get_devname(const char *token)
353{
354 char * dev_name;
355
356 if (!(dev_name = blkid_get_devname(NULL, token, NULL)))
357 bb_error_msg_and_die("Unable to resolve '%s'", token);
358 return dev_name;
376} 359}
377 360
378#ifdef CONFIG_E2LABEL 361#ifdef CONFIG_E2LABEL
@@ -383,9 +366,7 @@ static void parse_e2label_options(int argc, char ** argv)
383 io_options = strchr(argv[1], '?'); 366 io_options = strchr(argv[1], '?');
384 if (io_options) 367 if (io_options)
385 *io_options++ = 0; 368 *io_options++ = 0;
386 device_name = blkid_get_devname(NULL, argv[1], NULL); 369 device_name = x_blkid_get_devname(argv[1]);
387 if (!device_name)
388 bb_error_msg_and_die("Unable to resolve '%s'", argv[1]);
389 if (argc == 3) { 370 if (argc == 3) {
390 open_flag = EXT2_FLAG_RW | EXT2_FLAG_JOURNAL_DEV_OK; 371 open_flag = EXT2_FLAG_RW | EXT2_FLAG_JOURNAL_DEV_OK;
391 L_flag = 1; 372 L_flag = 1;
@@ -393,6 +374,8 @@ static void parse_e2label_options(int argc, char ** argv)
393 } else 374 } else
394 print_label++; 375 print_label++;
395} 376}
377#else
378#define parse_e2label_options(x,y)
396#endif 379#endif
397 380
398static time_t parse_time(char *str) 381static time_t parse_time(char *str)
@@ -425,17 +408,14 @@ static void parse_tune2fs_options(int argc, char **argv)
425{ 408{
426 int c; 409 int c;
427 char * tmp; 410 char * tmp;
428 struct group * gr;
429 struct passwd * pw;
430 411
431 printf("tune2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE); 412 printf("tune2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE);
432 while ((c = getopt(argc, argv, "c:e:fg:i:jlm:o:r:s:u:C:J:L:M:O:T:U:")) != EOF) 413 while ((c = getopt(argc, argv, "c:e:fg:i:jlm:o:r:s:u:C:J:L:M:O:T:U:")) != EOF)
433 switch (c) 414 switch (c)
434 { 415 {
435 case 'c': 416 case 'c':
436 max_mount_count = strtol (optarg, &tmp, 0); 417 if (safe_strtoi(optarg, &max_mount_count) || max_mount_count > 16000) {
437 if (*tmp || max_mount_count > 16000) { 418 goto MOUNTS_COUNT_ERROR;
438 bb_error_msg_and_die("bad mounts count - %s", optarg);
439 } 419 }
440 if (max_mount_count == 0) 420 if (max_mount_count == 0)
441 max_mount_count = -1; 421 max_mount_count = -1;
@@ -443,8 +423,8 @@ static void parse_tune2fs_options(int argc, char **argv)
443 open_flag = EXT2_FLAG_RW; 423 open_flag = EXT2_FLAG_RW;
444 break; 424 break;
445 case 'C': 425 case 'C':
446 mount_count = strtoul (optarg, &tmp, 0); 426 if (safe_strtoi(optarg, &mount_count) || mount_count > 16000) {
447 if (*tmp || mount_count > 16000) { 427MOUNTS_COUNT_ERROR:
448 bb_error_msg_and_die("bad mounts count - %s", optarg); 428 bb_error_msg_and_die("bad mounts count - %s", optarg);
449 } 429 }
450 C_flag = 1; 430 C_flag = 1;
@@ -467,19 +447,8 @@ static void parse_tune2fs_options(int argc, char **argv)
467 f_flag = 1; 447 f_flag = 1;
468 break; 448 break;
469 case 'g': 449 case 'g':
470 resgid = strtoul (optarg, &tmp, 0); 450 if (safe_strtoul(optarg, &resgid))
471 if (*tmp) { 451 resgid = bb_xgetgrnam(optarg);
472 gr = getgrnam (optarg);
473 if (gr == NULL)
474 tmp = optarg;
475 else {
476 resgid = gr->gr_gid;
477 *tmp =0;
478 }
479 }
480 if (*tmp) {
481 bb_error_msg_and_die("bad gid/group name - %s", optarg);
482 }
483 g_flag = 1; 452 g_flag = 1;
484 open_flag = EXT2_FLAG_RW; 453 open_flag = EXT2_FLAG_RW;
485 break; 454 break;
@@ -532,8 +501,7 @@ static void parse_tune2fs_options(int argc, char **argv)
532 EXT2_FLAG_JOURNAL_DEV_OK; 501 EXT2_FLAG_JOURNAL_DEV_OK;
533 break; 502 break;
534 case 'm': 503 case 'm':
535 reserved_ratio = strtoul (optarg, &tmp, 0); 504 if(safe_strtoul(optarg, &reserved_ratio) || reserved_ratio > 50) {
536 if (*tmp || reserved_ratio > 50) {
537 bb_error_msg_and_die("bad reserved block ratio - %s", optarg); 505 bb_error_msg_and_die("bad reserved block ratio - %s", optarg);
538 } 506 }
539 m_flag = 1; 507 m_flag = 1;
@@ -560,8 +528,7 @@ static void parse_tune2fs_options(int argc, char **argv)
560 open_flag = EXT2_FLAG_RW; 528 open_flag = EXT2_FLAG_RW;
561 break; 529 break;
562 case 'r': 530 case 'r':
563 reserved_blocks = strtoul (optarg, &tmp, 0); 531 if(safe_strtoul(optarg, &reserved_blocks)) {
564 if (*tmp) {
565 bb_error_msg_and_die("bad reserved blocks count - %s", optarg); 532 bb_error_msg_and_die("bad reserved blocks count - %s", optarg);
566 } 533 }
567 r_flag = 1; 534 r_flag = 1;
@@ -577,19 +544,8 @@ static void parse_tune2fs_options(int argc, char **argv)
577 open_flag = EXT2_FLAG_RW; 544 open_flag = EXT2_FLAG_RW;
578 break; 545 break;
579 case 'u': 546 case 'u':
580 resuid = strtoul (optarg, &tmp, 0); 547 if (safe_strtoul(optarg, &resuid))
581 if (*tmp) { 548 resuid = bb_xgetpwnam(optarg);
582 pw = getpwnam (optarg);
583 if (pw == NULL)
584 tmp = optarg;
585 else {
586 resuid = pw->pw_uid;
587 *tmp = 0;
588 }
589 }
590 if (*tmp) {
591 bb_error_msg_and_die("bad uid/user name - %s", optarg);
592 }
593 u_flag = 1; 549 u_flag = 1;
594 open_flag = EXT2_FLAG_RW; 550 open_flag = EXT2_FLAG_RW;
595 break; 551 break;
@@ -609,48 +565,45 @@ static void parse_tune2fs_options(int argc, char **argv)
609 io_options = strchr(argv[optind], '?'); 565 io_options = strchr(argv[optind], '?');
610 if (io_options) 566 if (io_options)
611 *io_options++ = 0; 567 *io_options++ = 0;
612 device_name = blkid_get_devname(NULL, argv[optind], NULL); 568 device_name = x_blkid_get_devname(argv[optind]);
613 if (!device_name)
614 bb_error_msg_and_die("Unable to resolve '%s'", argv[optind]);
615} 569}
616 570
617#ifdef CONFIG_FINDFS 571#ifdef CONFIG_FINDFS
618static attribute_noreturn void do_findfs(int argc, char **argv) 572static attribute_noreturn void do_findfs(int argc, char **argv)
619{ 573{
620 char *dev;
621
622 if ((argc != 2) || 574 if ((argc != 2) ||
623 (strncmp(argv[1], "LABEL=", 6) && strncmp(argv[1], "UUID=", 5))) 575 (strncmp(argv[1], "LABEL=", 6) && strncmp(argv[1], "UUID=", 5)))
624 bb_show_usage(); 576 bb_show_usage();
625 dev = blkid_get_devname(NULL, argv[1], NULL); 577 device_name = x_blkid_get_devname(argv[1]);
626 if (!dev) 578 puts(device_name);
627 bb_error_msg_and_die("Unable to resolve '%s'", argv[1]);
628 puts(dev);
629 exit(0); 579 exit(0);
630} 580}
581#else
582#define do_findfs(x, y)
631#endif 583#endif
632 584
585static void clean_up(void)
586{
587 if (ENABLE_FEATURE_CLEAN_UP && device_name) free(device_name);
588 if (ENABLE_FEATURE_CLEAN_UP && journal_device) free(journal_device);
589}
590
633int tune2fs_main(int argc, char **argv) 591int tune2fs_main(int argc, char **argv)
634{ 592{
635 errcode_t retval; 593 errcode_t retval;
636 ext2_filsys fs; 594 ext2_filsys fs;
637 struct ext2_super_block *sb; 595 struct ext2_super_block *sb;
638 io_manager io_ptr; 596 io_manager io_ptr;
639#if defined(CONFIG_FINDFS) || defined(CONFIG_E2LABEL)
640 char *program_name = basename(argv[0]);
641#endif
642 597
643#ifdef CONFIG_FINDFS 598 if (ENABLE_FEATURE_CLEAN_UP)
644 if (strcmp(program_name, "findfs") == 0) 599 atexit(clean_up);
645 do_findfs(argc, argv); 600
646#endif 601 if (ENABLE_FINDFS && (bb_applet_name[0] == 'f')) /* findfs */
647 602 do_findfs(argc, argv); /* no return */
648#ifdef CONFIG_E2LABEL 603 else if (ENABLE_E2LABEL && (bb_applet_name[0] == 'e')) /* e2label */
649 if (strcmp(program_name, "e2label") == 0)
650 parse_e2label_options(argc, argv); 604 parse_e2label_options(argc, argv);
651 else 605 else
652#endif 606 parse_tune2fs_options(argc, argv); /* tune2fs */
653 parse_tune2fs_options(argc, argv);
654 607
655 io_ptr = unix_io_manager; 608 io_ptr = unix_io_manager;
656 retval = ext2fs_open2(device_name, io_options, open_flag, 609 retval = ext2fs_open2(device_name, io_options, open_flag,
@@ -662,7 +615,7 @@ int tune2fs_main(int argc, char **argv)
662 /* For e2label emulation */ 615 /* For e2label emulation */
663 printf("%.*s\n", (int) sizeof(sb->s_volume_name), 616 printf("%.*s\n", (int) sizeof(sb->s_volume_name),
664 sb->s_volume_name); 617 sb->s_volume_name);
665 exit(0); 618 return 0;
666 } 619 }
667 retval = ext2fs_check_if_mounted(device_name, &mount_flags); 620 retval = ext2fs_check_if_mounted(device_name, &mount_flags);
668 if (retval) 621 if (retval)