diff options
author | Yan, Zheng <zyan@redhat.com> | 2016-03-12 00:20:48 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2016-03-25 13:51:54 -0400 |
commit | 132ca7e1de1e3217af06bce2beb3aa13c3edc7f6 (patch) | |
tree | 261fc4a7546c4a87664de1a8af5922d4addcb2a5 | |
parent | 4531126753aaf936e2674d28245400c6559ef0ee (diff) |
ceph: fix mounting same fs multiple times
Now __ceph_open_session() only accepts closed client. An opened
client will tigger BUG_ON().
Signed-off-by: Yan, Zheng <zyan@redhat.com>
-rw-r--r-- | fs/ceph/super.c | 33 |
1 files changed, 15 insertions, 18 deletions
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 715282a92a07..c973043deb0e 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
@@ -793,22 +793,20 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc, | |||
793 | struct dentry *root; | 793 | struct dentry *root; |
794 | int first = 0; /* first vfsmount for this super_block */ | 794 | int first = 0; /* first vfsmount for this super_block */ |
795 | 795 | ||
796 | dout("mount start\n"); | 796 | dout("mount start %p\n", fsc); |
797 | mutex_lock(&fsc->client->mount_mutex); | 797 | mutex_lock(&fsc->client->mount_mutex); |
798 | 798 | ||
799 | err = __ceph_open_session(fsc->client, started); | 799 | if (!fsc->sb->s_root) { |
800 | if (err < 0) | 800 | err = __ceph_open_session(fsc->client, started); |
801 | goto out; | 801 | if (err < 0) |
802 | goto out; | ||
802 | 803 | ||
803 | dout("mount opening root\n"); | 804 | dout("mount opening root\n"); |
804 | root = open_root_dentry(fsc, "", started); | 805 | root = open_root_dentry(fsc, "", started); |
805 | if (IS_ERR(root)) { | 806 | if (IS_ERR(root)) { |
806 | err = PTR_ERR(root); | 807 | err = PTR_ERR(root); |
807 | goto out; | 808 | goto out; |
808 | } | 809 | } |
809 | if (fsc->sb->s_root) { | ||
810 | dput(root); | ||
811 | } else { | ||
812 | fsc->sb->s_root = root; | 810 | fsc->sb->s_root = root; |
813 | first = 1; | 811 | first = 1; |
814 | 812 | ||
@@ -818,6 +816,7 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc, | |||
818 | } | 816 | } |
819 | 817 | ||
820 | if (path[0] == 0) { | 818 | if (path[0] == 0) { |
819 | root = fsc->sb->s_root; | ||
821 | dget(root); | 820 | dget(root); |
822 | } else { | 821 | } else { |
823 | dout("mount opening base mountpoint\n"); | 822 | dout("mount opening base mountpoint\n"); |
@@ -833,16 +832,14 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc, | |||
833 | mutex_unlock(&fsc->client->mount_mutex); | 832 | mutex_unlock(&fsc->client->mount_mutex); |
834 | return root; | 833 | return root; |
835 | 834 | ||
836 | out: | ||
837 | mutex_unlock(&fsc->client->mount_mutex); | ||
838 | return ERR_PTR(err); | ||
839 | |||
840 | fail: | 835 | fail: |
841 | if (first) { | 836 | if (first) { |
842 | dput(fsc->sb->s_root); | 837 | dput(fsc->sb->s_root); |
843 | fsc->sb->s_root = NULL; | 838 | fsc->sb->s_root = NULL; |
844 | } | 839 | } |
845 | goto out; | 840 | out: |
841 | mutex_unlock(&fsc->client->mount_mutex); | ||
842 | return ERR_PTR(err); | ||
846 | } | 843 | } |
847 | 844 | ||
848 | static int ceph_set_super(struct super_block *s, void *data) | 845 | static int ceph_set_super(struct super_block *s, void *data) |