aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nilfs2/super.c73
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
786static 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))