diff options
-rw-r--r-- | fs/nilfs2/super.c | 73 |
1 files changed, 45 insertions, 28 deletions
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 1e12930f8b94..ebeb746c4845 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -783,6 +783,40 @@ static int nilfs_get_root_dentry(struct super_block *sb, | |||
783 | return ret; | 783 | return ret; |
784 | } | 784 | } |
785 | 785 | ||
786 | static int nilfs_attach_snapshot(struct super_block *s, __u64 cno, | ||
787 | struct dentry **root_dentry) | ||
788 | { | ||
789 | struct the_nilfs *nilfs = NILFS_SB(s)->s_nilfs; | ||
790 | struct nilfs_root *root; | ||
791 | int ret; | ||
792 | |||
793 | down_read(&nilfs->ns_segctor_sem); | ||
794 | ret = nilfs_cpfile_is_snapshot(nilfs->ns_cpfile, cno); | ||
795 | up_read(&nilfs->ns_segctor_sem); | ||
796 | if (ret < 0) { | ||
797 | ret = (ret == -ENOENT) ? -EINVAL : ret; | ||
798 | goto out; | ||
799 | } else if (!ret) { | ||
800 | printk(KERN_ERR "NILFS: The specified checkpoint is " | ||
801 | "not a snapshot (checkpoint number=%llu).\n", | ||
802 | (unsigned long long)cno); | ||
803 | ret = -EINVAL; | ||
804 | goto out; | ||
805 | } | ||
806 | |||
807 | ret = nilfs_attach_checkpoint(NILFS_SB(s), cno, false, &root); | ||
808 | if (ret) { | ||
809 | printk(KERN_ERR "NILFS: error loading snapshot " | ||
810 | "(checkpoint number=%llu).\n", | ||
811 | (unsigned long long)cno); | ||
812 | goto out; | ||
813 | } | ||
814 | ret = nilfs_get_root_dentry(s, root, root_dentry); | ||
815 | nilfs_put_root(root); | ||
816 | out: | ||
817 | return ret; | ||
818 | } | ||
819 | |||
786 | /** | 820 | /** |
787 | * nilfs_fill_super() - initialize a super block instance | 821 | * nilfs_fill_super() - initialize a super block instance |
788 | * @sb: super_block | 822 | * @sb: super_block |
@@ -800,7 +834,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
800 | struct nilfs_sb_info *sbi; | 834 | struct nilfs_sb_info *sbi; |
801 | struct nilfs_root *fsroot; | 835 | struct nilfs_root *fsroot; |
802 | __u64 cno; | 836 | __u64 cno; |
803 | int err, curr_mnt; | 837 | int err; |
804 | 838 | ||
805 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); | 839 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); |
806 | if (!sbi) | 840 | if (!sbi) |
@@ -841,35 +875,17 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
841 | if (err) | 875 | if (err) |
842 | goto failed_sbi; | 876 | goto failed_sbi; |
843 | 877 | ||
844 | cno = nilfs_last_cno(nilfs); | 878 | if (nilfs_test_opt(sbi, SNAPSHOT)) { |
845 | curr_mnt = true; | 879 | err = nilfs_attach_snapshot(sb, sbi->s_snapshot_cno, |
846 | 880 | &sb->s_root); | |
847 | if (sb->s_flags & MS_RDONLY) { | 881 | if (err) |
848 | if (nilfs_test_opt(sbi, SNAPSHOT)) { | 882 | goto failed_sbi; |
849 | down_read(&nilfs->ns_segctor_sem); | 883 | |
850 | err = nilfs_cpfile_is_snapshot(nilfs->ns_cpfile, | 884 | goto add_to_supers; |
851 | sbi->s_snapshot_cno); | ||
852 | up_read(&nilfs->ns_segctor_sem); | ||
853 | if (err < 0) { | ||
854 | if (err == -ENOENT) | ||
855 | err = -EINVAL; | ||
856 | goto failed_sbi; | ||
857 | } | ||
858 | if (!err) { | ||
859 | printk(KERN_ERR | ||
860 | "NILFS: The specified checkpoint is " | ||
861 | "not a snapshot " | ||
862 | "(checkpoint number=%llu).\n", | ||
863 | (unsigned long long)sbi->s_snapshot_cno); | ||
864 | err = -EINVAL; | ||
865 | goto failed_sbi; | ||
866 | } | ||
867 | cno = sbi->s_snapshot_cno; | ||
868 | curr_mnt = false; | ||
869 | } | ||
870 | } | 885 | } |
871 | 886 | ||
872 | err = nilfs_attach_checkpoint(sbi, cno, curr_mnt, &fsroot); | 887 | cno = nilfs_last_cno(nilfs); |
888 | err = nilfs_attach_checkpoint(sbi, cno, true, &fsroot); | ||
873 | if (err) { | 889 | if (err) { |
874 | printk(KERN_ERR "NILFS: error loading a checkpoint" | 890 | printk(KERN_ERR "NILFS: error loading a checkpoint" |
875 | " (checkpoint number=%llu).\n", (unsigned long long)cno); | 891 | " (checkpoint number=%llu).\n", (unsigned long long)cno); |
@@ -894,6 +910,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
894 | up_write(&nilfs->ns_sem); | 910 | up_write(&nilfs->ns_sem); |
895 | } | 911 | } |
896 | 912 | ||
913 | add_to_supers: | ||
897 | down_write(&nilfs->ns_super_sem); | 914 | down_write(&nilfs->ns_super_sem); |
898 | list_add(&sbi->s_list, &nilfs->ns_supers); | 915 | list_add(&sbi->s_list, &nilfs->ns_supers); |
899 | if (!nilfs_test_opt(sbi, SNAPSHOT)) | 916 | if (!nilfs_test_opt(sbi, SNAPSHOT)) |