diff options
Diffstat (limited to 'e2fsprogs/tune2fs.c')
-rw-r--r-- | e2fsprogs/tune2fs.c | 183 |
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 | ||
53 | static char * device_name; | 53 | static char * device_name = NULL; |
54 | static char * new_label, *new_last_mounted, *new_UUID; | 54 | static char * new_label, *new_last_mounted, *new_UUID; |
55 | static char * io_options; | 55 | static char * io_options; |
56 | static int c_flag, C_flag, e_flag, f_flag, g_flag, i_flag, l_flag, L_flag; | 56 | static 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; | |||
66 | static char *mntopts_cmd; | 66 | static char *mntopts_cmd; |
67 | 67 | ||
68 | static int journal_size, journal_flags; | 68 | static int journal_size, journal_flags; |
69 | static char *journal_device; | 69 | static char *journal_device = NULL; |
70 | 70 | ||
71 | static const char *please_fsck = "Please run e2fsck on the filesystem\n"; | 71 | static 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"; |
218 | REMOVE_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 | */ |
318 | static void add_journal(ext2_filsys fs) | 328 | static 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 | ||
372 | err: | 349 | /* |
373 | if (journal_device) | 350 | * Busybox stuff |
374 | free(journal_device); | 351 | */ |
375 | exit(1); | 352 | static 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 | ||
398 | static time_t parse_time(char *str) | 381 | static 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) { | 427 | MOUNTS_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 |
618 | static attribute_noreturn void do_findfs(int argc, char **argv) | 572 | static 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 | ||
585 | static 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 | |||
633 | int tune2fs_main(int argc, char **argv) | 591 | int 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) |