diff options
Diffstat (limited to 'fs/nilfs2/super.c')
-rw-r--r-- | fs/nilfs2/super.c | 88 |
1 files changed, 25 insertions, 63 deletions
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 644e66727dd0..5403b3ef3a42 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -363,14 +363,10 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno) | |||
363 | list_add(&sbi->s_list, &nilfs->ns_supers); | 363 | list_add(&sbi->s_list, &nilfs->ns_supers); |
364 | up_write(&nilfs->ns_super_sem); | 364 | up_write(&nilfs->ns_super_sem); |
365 | 365 | ||
366 | sbi->s_ifile = nilfs_mdt_new(nilfs, sbi->s_super, NILFS_IFILE_INO); | 366 | sbi->s_ifile = nilfs_ifile_new(sbi, nilfs->ns_inode_size); |
367 | if (!sbi->s_ifile) | 367 | if (!sbi->s_ifile) |
368 | return -ENOMEM; | 368 | return -ENOMEM; |
369 | 369 | ||
370 | err = nilfs_palloc_init_blockgroup(sbi->s_ifile, nilfs->ns_inode_size); | ||
371 | if (unlikely(err)) | ||
372 | goto failed; | ||
373 | |||
374 | down_read(&nilfs->ns_segctor_sem); | 370 | down_read(&nilfs->ns_segctor_sem); |
375 | err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp, | 371 | err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp, |
376 | &bh_cp); | 372 | &bh_cp); |
@@ -411,7 +407,6 @@ void nilfs_detach_checkpoint(struct nilfs_sb_info *sbi) | |||
411 | { | 407 | { |
412 | struct the_nilfs *nilfs = sbi->s_nilfs; | 408 | struct the_nilfs *nilfs = sbi->s_nilfs; |
413 | 409 | ||
414 | nilfs_mdt_clear(sbi->s_ifile); | ||
415 | nilfs_mdt_destroy(sbi->s_ifile); | 410 | nilfs_mdt_destroy(sbi->s_ifile); |
416 | sbi->s_ifile = NULL; | 411 | sbi->s_ifile = NULL; |
417 | down_write(&nilfs->ns_super_sem); | 412 | down_write(&nilfs->ns_super_sem); |
@@ -419,22 +414,6 @@ void nilfs_detach_checkpoint(struct nilfs_sb_info *sbi) | |||
419 | up_write(&nilfs->ns_super_sem); | 414 | up_write(&nilfs->ns_super_sem); |
420 | } | 415 | } |
421 | 416 | ||
422 | static int nilfs_mark_recovery_complete(struct nilfs_sb_info *sbi) | ||
423 | { | ||
424 | struct the_nilfs *nilfs = sbi->s_nilfs; | ||
425 | int err = 0; | ||
426 | |||
427 | down_write(&nilfs->ns_sem); | ||
428 | if (!(nilfs->ns_mount_state & NILFS_VALID_FS)) { | ||
429 | nilfs->ns_mount_state |= NILFS_VALID_FS; | ||
430 | err = nilfs_commit_super(sbi, 1); | ||
431 | if (likely(!err)) | ||
432 | printk(KERN_INFO "NILFS: recovery complete.\n"); | ||
433 | } | ||
434 | up_write(&nilfs->ns_sem); | ||
435 | return err; | ||
436 | } | ||
437 | |||
438 | static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 417 | static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
439 | { | 418 | { |
440 | struct super_block *sb = dentry->d_sb; | 419 | struct super_block *sb = dentry->d_sb; |
@@ -490,7 +469,7 @@ static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
490 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | 469 | struct nilfs_sb_info *sbi = NILFS_SB(sb); |
491 | 470 | ||
492 | if (!nilfs_test_opt(sbi, BARRIER)) | 471 | if (!nilfs_test_opt(sbi, BARRIER)) |
493 | seq_printf(seq, ",barrier=off"); | 472 | seq_printf(seq, ",nobarrier"); |
494 | if (nilfs_test_opt(sbi, SNAPSHOT)) | 473 | if (nilfs_test_opt(sbi, SNAPSHOT)) |
495 | seq_printf(seq, ",cp=%llu", | 474 | seq_printf(seq, ",cp=%llu", |
496 | (unsigned long long int)sbi->s_snapshot_cno); | 475 | (unsigned long long int)sbi->s_snapshot_cno); |
@@ -500,6 +479,8 @@ static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
500 | seq_printf(seq, ",errors=panic"); | 479 | seq_printf(seq, ",errors=panic"); |
501 | if (nilfs_test_opt(sbi, STRICT_ORDER)) | 480 | if (nilfs_test_opt(sbi, STRICT_ORDER)) |
502 | seq_printf(seq, ",order=strict"); | 481 | seq_printf(seq, ",order=strict"); |
482 | if (nilfs_test_opt(sbi, NORECOVERY)) | ||
483 | seq_printf(seq, ",norecovery"); | ||
503 | 484 | ||
504 | return 0; | 485 | return 0; |
505 | } | 486 | } |
@@ -568,7 +549,7 @@ static const struct export_operations nilfs_export_ops = { | |||
568 | 549 | ||
569 | enum { | 550 | enum { |
570 | Opt_err_cont, Opt_err_panic, Opt_err_ro, | 551 | Opt_err_cont, Opt_err_panic, Opt_err_ro, |
571 | Opt_barrier, Opt_snapshot, Opt_order, | 552 | Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery, |
572 | Opt_err, | 553 | Opt_err, |
573 | }; | 554 | }; |
574 | 555 | ||
@@ -576,25 +557,13 @@ static match_table_t tokens = { | |||
576 | {Opt_err_cont, "errors=continue"}, | 557 | {Opt_err_cont, "errors=continue"}, |
577 | {Opt_err_panic, "errors=panic"}, | 558 | {Opt_err_panic, "errors=panic"}, |
578 | {Opt_err_ro, "errors=remount-ro"}, | 559 | {Opt_err_ro, "errors=remount-ro"}, |
579 | {Opt_barrier, "barrier=%s"}, | 560 | {Opt_nobarrier, "nobarrier"}, |
580 | {Opt_snapshot, "cp=%u"}, | 561 | {Opt_snapshot, "cp=%u"}, |
581 | {Opt_order, "order=%s"}, | 562 | {Opt_order, "order=%s"}, |
563 | {Opt_norecovery, "norecovery"}, | ||
582 | {Opt_err, NULL} | 564 | {Opt_err, NULL} |
583 | }; | 565 | }; |
584 | 566 | ||
585 | static int match_bool(substring_t *s, int *result) | ||
586 | { | ||
587 | int len = s->to - s->from; | ||
588 | |||
589 | if (strncmp(s->from, "on", len) == 0) | ||
590 | *result = 1; | ||
591 | else if (strncmp(s->from, "off", len) == 0) | ||
592 | *result = 0; | ||
593 | else | ||
594 | return 1; | ||
595 | return 0; | ||
596 | } | ||
597 | |||
598 | static int parse_options(char *options, struct super_block *sb) | 567 | static int parse_options(char *options, struct super_block *sb) |
599 | { | 568 | { |
600 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | 569 | struct nilfs_sb_info *sbi = NILFS_SB(sb); |
@@ -612,13 +581,8 @@ static int parse_options(char *options, struct super_block *sb) | |||
612 | 581 | ||
613 | token = match_token(p, tokens, args); | 582 | token = match_token(p, tokens, args); |
614 | switch (token) { | 583 | switch (token) { |
615 | case Opt_barrier: | 584 | case Opt_nobarrier: |
616 | if (match_bool(&args[0], &option)) | 585 | nilfs_clear_opt(sbi, BARRIER); |
617 | return 0; | ||
618 | if (option) | ||
619 | nilfs_set_opt(sbi, BARRIER); | ||
620 | else | ||
621 | nilfs_clear_opt(sbi, BARRIER); | ||
622 | break; | 586 | break; |
623 | case Opt_order: | 587 | case Opt_order: |
624 | if (strcmp(args[0].from, "relaxed") == 0) | 588 | if (strcmp(args[0].from, "relaxed") == 0) |
@@ -647,6 +611,9 @@ static int parse_options(char *options, struct super_block *sb) | |||
647 | sbi->s_snapshot_cno = option; | 611 | sbi->s_snapshot_cno = option; |
648 | nilfs_set_opt(sbi, SNAPSHOT); | 612 | nilfs_set_opt(sbi, SNAPSHOT); |
649 | break; | 613 | break; |
614 | case Opt_norecovery: | ||
615 | nilfs_set_opt(sbi, NORECOVERY); | ||
616 | break; | ||
650 | default: | 617 | default: |
651 | printk(KERN_ERR | 618 | printk(KERN_ERR |
652 | "NILFS: Unrecognized mount option \"%s\"\n", p); | 619 | "NILFS: Unrecognized mount option \"%s\"\n", p); |
@@ -672,9 +639,7 @@ static int nilfs_setup_super(struct nilfs_sb_info *sbi) | |||
672 | int mnt_count = le16_to_cpu(sbp->s_mnt_count); | 639 | int mnt_count = le16_to_cpu(sbp->s_mnt_count); |
673 | 640 | ||
674 | /* nilfs->sem must be locked by the caller. */ | 641 | /* nilfs->sem must be locked by the caller. */ |
675 | if (!(nilfs->ns_mount_state & NILFS_VALID_FS)) { | 642 | if (nilfs->ns_mount_state & NILFS_ERROR_FS) { |
676 | printk(KERN_WARNING "NILFS warning: mounting unchecked fs\n"); | ||
677 | } else if (nilfs->ns_mount_state & NILFS_ERROR_FS) { | ||
678 | printk(KERN_WARNING | 643 | printk(KERN_WARNING |
679 | "NILFS warning: mounting fs with errors\n"); | 644 | "NILFS warning: mounting fs with errors\n"); |
680 | #if 0 | 645 | #if 0 |
@@ -782,11 +747,10 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
782 | sb->s_root = NULL; | 747 | sb->s_root = NULL; |
783 | sb->s_time_gran = 1; | 748 | sb->s_time_gran = 1; |
784 | 749 | ||
785 | if (!nilfs_loaded(nilfs)) { | 750 | err = load_nilfs(nilfs, sbi); |
786 | err = load_nilfs(nilfs, sbi); | 751 | if (err) |
787 | if (err) | 752 | goto failed_sbi; |
788 | goto failed_sbi; | 753 | |
789 | } | ||
790 | cno = nilfs_last_cno(nilfs); | 754 | cno = nilfs_last_cno(nilfs); |
791 | 755 | ||
792 | if (sb->s_flags & MS_RDONLY) { | 756 | if (sb->s_flags & MS_RDONLY) { |
@@ -854,12 +818,6 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
854 | up_write(&nilfs->ns_sem); | 818 | up_write(&nilfs->ns_sem); |
855 | } | 819 | } |
856 | 820 | ||
857 | err = nilfs_mark_recovery_complete(sbi); | ||
858 | if (unlikely(err)) { | ||
859 | printk(KERN_ERR "NILFS: recovery failed.\n"); | ||
860 | goto failed_root; | ||
861 | } | ||
862 | |||
863 | down_write(&nilfs->ns_super_sem); | 821 | down_write(&nilfs->ns_super_sem); |
864 | if (!nilfs_test_opt(sbi, SNAPSHOT)) | 822 | if (!nilfs_test_opt(sbi, SNAPSHOT)) |
865 | nilfs->ns_current = sbi; | 823 | nilfs->ns_current = sbi; |
@@ -867,10 +825,6 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
867 | 825 | ||
868 | return 0; | 826 | return 0; |
869 | 827 | ||
870 | failed_root: | ||
871 | dput(sb->s_root); | ||
872 | sb->s_root = NULL; | ||
873 | |||
874 | failed_segctor: | 828 | failed_segctor: |
875 | nilfs_detach_segment_constructor(sbi); | 829 | nilfs_detach_segment_constructor(sbi); |
876 | 830 | ||
@@ -915,6 +869,14 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) | |||
915 | goto restore_opts; | 869 | goto restore_opts; |
916 | } | 870 | } |
917 | 871 | ||
872 | if (!nilfs_valid_fs(nilfs)) { | ||
873 | printk(KERN_WARNING "NILFS (device %s): couldn't " | ||
874 | "remount because the filesystem is in an " | ||
875 | "incomplete recovery state.\n", sb->s_id); | ||
876 | err = -EINVAL; | ||
877 | goto restore_opts; | ||
878 | } | ||
879 | |||
918 | if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) | 880 | if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) |
919 | goto out; | 881 | goto out; |
920 | if (*flags & MS_RDONLY) { | 882 | if (*flags & MS_RDONLY) { |