diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /fs/nilfs2/super.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'fs/nilfs2/super.c')
-rw-r--r-- | fs/nilfs2/super.c | 111 |
1 files changed, 38 insertions, 73 deletions
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 644e66727dd0..48145f505a6a 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -96,9 +96,6 @@ void nilfs_error(struct super_block *sb, const char *function, | |||
96 | if (!(sb->s_flags & MS_RDONLY)) { | 96 | if (!(sb->s_flags & MS_RDONLY)) { |
97 | struct the_nilfs *nilfs = sbi->s_nilfs; | 97 | struct the_nilfs *nilfs = sbi->s_nilfs; |
98 | 98 | ||
99 | if (!nilfs_test_opt(sbi, ERRORS_CONT)) | ||
100 | nilfs_detach_segment_constructor(sbi); | ||
101 | |||
102 | down_write(&nilfs->ns_sem); | 99 | down_write(&nilfs->ns_sem); |
103 | if (!(nilfs->ns_mount_state & NILFS_ERROR_FS)) { | 100 | if (!(nilfs->ns_mount_state & NILFS_ERROR_FS)) { |
104 | nilfs->ns_mount_state |= NILFS_ERROR_FS; | 101 | nilfs->ns_mount_state |= NILFS_ERROR_FS; |
@@ -301,7 +298,7 @@ int nilfs_commit_super(struct nilfs_sb_info *sbi, int dupsb) | |||
301 | memcpy(sbp[1], sbp[0], nilfs->ns_sbsize); | 298 | memcpy(sbp[1], sbp[0], nilfs->ns_sbsize); |
302 | nilfs->ns_sbwtime[1] = t; | 299 | nilfs->ns_sbwtime[1] = t; |
303 | } | 300 | } |
304 | sbi->s_super->s_dirt = 0; | 301 | clear_nilfs_sb_dirty(nilfs); |
305 | return nilfs_sync_super(sbi, dupsb); | 302 | return nilfs_sync_super(sbi, dupsb); |
306 | } | 303 | } |
307 | 304 | ||
@@ -345,7 +342,7 @@ static int nilfs_sync_fs(struct super_block *sb, int wait) | |||
345 | err = nilfs_construct_segment(sb); | 342 | err = nilfs_construct_segment(sb); |
346 | 343 | ||
347 | down_write(&nilfs->ns_sem); | 344 | down_write(&nilfs->ns_sem); |
348 | if (sb->s_dirt) | 345 | if (nilfs_sb_dirty(nilfs)) |
349 | nilfs_commit_super(sbi, 1); | 346 | nilfs_commit_super(sbi, 1); |
350 | up_write(&nilfs->ns_sem); | 347 | up_write(&nilfs->ns_sem); |
351 | 348 | ||
@@ -363,14 +360,10 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno) | |||
363 | list_add(&sbi->s_list, &nilfs->ns_supers); | 360 | list_add(&sbi->s_list, &nilfs->ns_supers); |
364 | up_write(&nilfs->ns_super_sem); | 361 | up_write(&nilfs->ns_super_sem); |
365 | 362 | ||
366 | sbi->s_ifile = nilfs_mdt_new(nilfs, sbi->s_super, NILFS_IFILE_INO); | 363 | sbi->s_ifile = nilfs_ifile_new(sbi, nilfs->ns_inode_size); |
367 | if (!sbi->s_ifile) | 364 | if (!sbi->s_ifile) |
368 | return -ENOMEM; | 365 | return -ENOMEM; |
369 | 366 | ||
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); | 367 | down_read(&nilfs->ns_segctor_sem); |
375 | err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp, | 368 | err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp, |
376 | &bh_cp); | 369 | &bh_cp); |
@@ -411,7 +404,6 @@ void nilfs_detach_checkpoint(struct nilfs_sb_info *sbi) | |||
411 | { | 404 | { |
412 | struct the_nilfs *nilfs = sbi->s_nilfs; | 405 | struct the_nilfs *nilfs = sbi->s_nilfs; |
413 | 406 | ||
414 | nilfs_mdt_clear(sbi->s_ifile); | ||
415 | nilfs_mdt_destroy(sbi->s_ifile); | 407 | nilfs_mdt_destroy(sbi->s_ifile); |
416 | sbi->s_ifile = NULL; | 408 | sbi->s_ifile = NULL; |
417 | down_write(&nilfs->ns_super_sem); | 409 | down_write(&nilfs->ns_super_sem); |
@@ -419,22 +411,6 @@ void nilfs_detach_checkpoint(struct nilfs_sb_info *sbi) | |||
419 | up_write(&nilfs->ns_super_sem); | 411 | up_write(&nilfs->ns_super_sem); |
420 | } | 412 | } |
421 | 413 | ||
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) | 414 | static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
439 | { | 415 | { |
440 | struct super_block *sb = dentry->d_sb; | 416 | struct super_block *sb = dentry->d_sb; |
@@ -460,7 +436,7 @@ static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
460 | /* | 436 | /* |
461 | * Compute the overhead | 437 | * Compute the overhead |
462 | * | 438 | * |
463 | * When distributing meta data blocks outside semgent structure, | 439 | * When distributing meta data blocks outside segment structure, |
464 | * We must count them as the overhead. | 440 | * We must count them as the overhead. |
465 | */ | 441 | */ |
466 | overhead = 0; | 442 | overhead = 0; |
@@ -490,7 +466,7 @@ static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
490 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | 466 | struct nilfs_sb_info *sbi = NILFS_SB(sb); |
491 | 467 | ||
492 | if (!nilfs_test_opt(sbi, BARRIER)) | 468 | if (!nilfs_test_opt(sbi, BARRIER)) |
493 | seq_printf(seq, ",barrier=off"); | 469 | seq_printf(seq, ",nobarrier"); |
494 | if (nilfs_test_opt(sbi, SNAPSHOT)) | 470 | if (nilfs_test_opt(sbi, SNAPSHOT)) |
495 | seq_printf(seq, ",cp=%llu", | 471 | seq_printf(seq, ",cp=%llu", |
496 | (unsigned long long int)sbi->s_snapshot_cno); | 472 | (unsigned long long int)sbi->s_snapshot_cno); |
@@ -500,6 +476,10 @@ static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
500 | seq_printf(seq, ",errors=panic"); | 476 | seq_printf(seq, ",errors=panic"); |
501 | if (nilfs_test_opt(sbi, STRICT_ORDER)) | 477 | if (nilfs_test_opt(sbi, STRICT_ORDER)) |
502 | seq_printf(seq, ",order=strict"); | 478 | seq_printf(seq, ",order=strict"); |
479 | if (nilfs_test_opt(sbi, NORECOVERY)) | ||
480 | seq_printf(seq, ",norecovery"); | ||
481 | if (nilfs_test_opt(sbi, DISCARD)) | ||
482 | seq_printf(seq, ",discard"); | ||
503 | 483 | ||
504 | return 0; | 484 | return 0; |
505 | } | 485 | } |
@@ -568,33 +548,22 @@ static const struct export_operations nilfs_export_ops = { | |||
568 | 548 | ||
569 | enum { | 549 | enum { |
570 | Opt_err_cont, Opt_err_panic, Opt_err_ro, | 550 | Opt_err_cont, Opt_err_panic, Opt_err_ro, |
571 | Opt_barrier, Opt_snapshot, Opt_order, | 551 | Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery, |
572 | Opt_err, | 552 | Opt_discard, Opt_err, |
573 | }; | 553 | }; |
574 | 554 | ||
575 | static match_table_t tokens = { | 555 | static match_table_t tokens = { |
576 | {Opt_err_cont, "errors=continue"}, | 556 | {Opt_err_cont, "errors=continue"}, |
577 | {Opt_err_panic, "errors=panic"}, | 557 | {Opt_err_panic, "errors=panic"}, |
578 | {Opt_err_ro, "errors=remount-ro"}, | 558 | {Opt_err_ro, "errors=remount-ro"}, |
579 | {Opt_barrier, "barrier=%s"}, | 559 | {Opt_nobarrier, "nobarrier"}, |
580 | {Opt_snapshot, "cp=%u"}, | 560 | {Opt_snapshot, "cp=%u"}, |
581 | {Opt_order, "order=%s"}, | 561 | {Opt_order, "order=%s"}, |
562 | {Opt_norecovery, "norecovery"}, | ||
563 | {Opt_discard, "discard"}, | ||
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,12 @@ 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; | ||
617 | case Opt_discard: | ||
618 | nilfs_set_opt(sbi, DISCARD); | ||
619 | break; | ||
650 | default: | 620 | default: |
651 | printk(KERN_ERR | 621 | printk(KERN_ERR |
652 | "NILFS: Unrecognized mount option \"%s\"\n", p); | 622 | "NILFS: Unrecognized mount option \"%s\"\n", p); |
@@ -672,9 +642,7 @@ static int nilfs_setup_super(struct nilfs_sb_info *sbi) | |||
672 | int mnt_count = le16_to_cpu(sbp->s_mnt_count); | 642 | int mnt_count = le16_to_cpu(sbp->s_mnt_count); |
673 | 643 | ||
674 | /* nilfs->sem must be locked by the caller. */ | 644 | /* nilfs->sem must be locked by the caller. */ |
675 | if (!(nilfs->ns_mount_state & NILFS_VALID_FS)) { | 645 | 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 | 646 | printk(KERN_WARNING |
679 | "NILFS warning: mounting fs with errors\n"); | 647 | "NILFS warning: mounting fs with errors\n"); |
680 | #if 0 | 648 | #if 0 |
@@ -781,12 +749,12 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
781 | sb->s_export_op = &nilfs_export_ops; | 749 | sb->s_export_op = &nilfs_export_ops; |
782 | sb->s_root = NULL; | 750 | sb->s_root = NULL; |
783 | sb->s_time_gran = 1; | 751 | sb->s_time_gran = 1; |
752 | sb->s_bdi = nilfs->ns_bdi; | ||
753 | |||
754 | err = load_nilfs(nilfs, sbi); | ||
755 | if (err) | ||
756 | goto failed_sbi; | ||
784 | 757 | ||
785 | if (!nilfs_loaded(nilfs)) { | ||
786 | err = load_nilfs(nilfs, sbi); | ||
787 | if (err) | ||
788 | goto failed_sbi; | ||
789 | } | ||
790 | cno = nilfs_last_cno(nilfs); | 758 | cno = nilfs_last_cno(nilfs); |
791 | 759 | ||
792 | if (sb->s_flags & MS_RDONLY) { | 760 | if (sb->s_flags & MS_RDONLY) { |
@@ -854,12 +822,6 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
854 | up_write(&nilfs->ns_sem); | 822 | up_write(&nilfs->ns_sem); |
855 | } | 823 | } |
856 | 824 | ||
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); | 825 | down_write(&nilfs->ns_super_sem); |
864 | if (!nilfs_test_opt(sbi, SNAPSHOT)) | 826 | if (!nilfs_test_opt(sbi, SNAPSHOT)) |
865 | nilfs->ns_current = sbi; | 827 | nilfs->ns_current = sbi; |
@@ -867,10 +829,6 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
867 | 829 | ||
868 | return 0; | 830 | return 0; |
869 | 831 | ||
870 | failed_root: | ||
871 | dput(sb->s_root); | ||
872 | sb->s_root = NULL; | ||
873 | |||
874 | failed_segctor: | 832 | failed_segctor: |
875 | nilfs_detach_segment_constructor(sbi); | 833 | nilfs_detach_segment_constructor(sbi); |
876 | 834 | ||
@@ -909,12 +867,20 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) | |||
909 | if ((*flags & MS_RDONLY) && | 867 | if ((*flags & MS_RDONLY) && |
910 | sbi->s_snapshot_cno != old_opts.snapshot_cno) { | 868 | sbi->s_snapshot_cno != old_opts.snapshot_cno) { |
911 | printk(KERN_WARNING "NILFS (device %s): couldn't " | 869 | printk(KERN_WARNING "NILFS (device %s): couldn't " |
912 | "remount to a different snapshot. \n", | 870 | "remount to a different snapshot.\n", |
913 | sb->s_id); | 871 | sb->s_id); |
914 | err = -EINVAL; | 872 | err = -EINVAL; |
915 | goto restore_opts; | 873 | goto restore_opts; |
916 | } | 874 | } |
917 | 875 | ||
876 | if (!nilfs_valid_fs(nilfs)) { | ||
877 | printk(KERN_WARNING "NILFS (device %s): couldn't " | ||
878 | "remount because the filesystem is in an " | ||
879 | "incomplete recovery state.\n", sb->s_id); | ||
880 | err = -EINVAL; | ||
881 | goto restore_opts; | ||
882 | } | ||
883 | |||
918 | if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) | 884 | if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) |
919 | goto out; | 885 | goto out; |
920 | if (*flags & MS_RDONLY) { | 886 | if (*flags & MS_RDONLY) { |
@@ -1156,8 +1122,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, | |||
1156 | /* Abandoning the newly allocated superblock */ | 1122 | /* Abandoning the newly allocated superblock */ |
1157 | mutex_unlock(&nilfs->ns_mount_mutex); | 1123 | mutex_unlock(&nilfs->ns_mount_mutex); |
1158 | put_nilfs(nilfs); | 1124 | put_nilfs(nilfs); |
1159 | up_write(&s->s_umount); | 1125 | deactivate_locked_super(s); |
1160 | deactivate_super(s); | ||
1161 | /* | 1126 | /* |
1162 | * deactivate_super() invokes close_bdev_exclusive(). | 1127 | * deactivate_super() invokes close_bdev_exclusive(). |
1163 | * We must finish all post-cleaning before this call; | 1128 | * We must finish all post-cleaning before this call; |