ceph: fix mounting same fs multiple times
authorYan, Zheng <zyan@redhat.com>
Sat, 12 Mar 2016 05:20:48 +0000 (13:20 +0800)
committerIlya Dryomov <idryomov@gmail.com>
Fri, 25 Mar 2016 17:51:54 +0000 (18:51 +0100)
Now __ceph_open_session() only accepts closed client. An opened
client will tigger BUG_ON().

Signed-off-by: Yan, Zheng <zyan@redhat.com>
fs/ceph/super.c

index 715282a..c973043 100644 (file)
@@ -793,22 +793,20 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc,
        struct dentry *root;
        int first = 0;   /* first vfsmount for this super_block */
 
-       dout("mount start\n");
+       dout("mount start %p\n", fsc);
        mutex_lock(&fsc->client->mount_mutex);
 
-       err = __ceph_open_session(fsc->client, started);
-       if (err < 0)
-               goto out;
+       if (!fsc->sb->s_root) {
+               err = __ceph_open_session(fsc->client, started);
+               if (err < 0)
+                       goto out;
 
-       dout("mount opening root\n");
-       root = open_root_dentry(fsc, "", started);
-       if (IS_ERR(root)) {
-               err = PTR_ERR(root);
-               goto out;
-       }
-       if (fsc->sb->s_root) {
-               dput(root);
-       } else {
+               dout("mount opening root\n");
+               root = open_root_dentry(fsc, "", started);
+               if (IS_ERR(root)) {
+                       err = PTR_ERR(root);
+                       goto out;
+               }
                fsc->sb->s_root = root;
                first = 1;
 
@@ -818,6 +816,7 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc,
        }
 
        if (path[0] == 0) {
+               root = fsc->sb->s_root;
                dget(root);
        } else {
                dout("mount opening base mountpoint\n");
@@ -833,16 +832,14 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc,
        mutex_unlock(&fsc->client->mount_mutex);
        return root;
 
-out:
-       mutex_unlock(&fsc->client->mount_mutex);
-       return ERR_PTR(err);
-
 fail:
        if (first) {
                dput(fsc->sb->s_root);
                fsc->sb->s_root = NULL;
        }
-       goto out;
+out:
+       mutex_unlock(&fsc->client->mount_mutex);
+       return ERR_PTR(err);
 }
 
 static int ceph_set_super(struct super_block *s, void *data)