diff options
author | Chengguang Xu <cgxu519@icloud.com> | 2018-02-09 07:40:59 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2018-02-26 10:20:07 -0500 |
commit | 18106734b512664a8541026519ce4b862498b6c3 (patch) | |
tree | f9cccd9207dda67d143d000a3464a9469853f2ca | |
parent | 937441f3a3158d5510ca8cc78a82453f57a96365 (diff) |
ceph: fix dentry leak when failing to init debugfs
When failing from ceph_fs_debugfs_init() in ceph_real_mount(),
there is lack of dput of root_dentry and it causes slab errors,
so change the calling order of ceph_fs_debugfs_init() and
open_root_dentry() and do some cleanups to avoid this issue.
Signed-off-by: Chengguang Xu <cgxu519@icloud.com>
Reviewed-by: "Yan, Zheng" <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
-rw-r--r-- | fs/ceph/super.c | 16 |
1 files changed, 5 insertions, 11 deletions
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index bfc85b22a190..1c470b453a9e 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
@@ -838,7 +838,6 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc) | |||
838 | int err; | 838 | int err; |
839 | unsigned long started = jiffies; /* note the start time */ | 839 | unsigned long started = jiffies; /* note the start time */ |
840 | struct dentry *root; | 840 | struct dentry *root; |
841 | int first = 0; /* first vfsmount for this super_block */ | ||
842 | 841 | ||
843 | dout("mount start %p\n", fsc); | 842 | dout("mount start %p\n", fsc); |
844 | mutex_lock(&fsc->client->mount_mutex); | 843 | mutex_lock(&fsc->client->mount_mutex); |
@@ -863,17 +862,17 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc) | |||
863 | path = fsc->mount_options->server_path + 1; | 862 | path = fsc->mount_options->server_path + 1; |
864 | dout("mount opening path %s\n", path); | 863 | dout("mount opening path %s\n", path); |
865 | } | 864 | } |
865 | |||
866 | err = ceph_fs_debugfs_init(fsc); | ||
867 | if (err < 0) | ||
868 | goto out; | ||
869 | |||
866 | root = open_root_dentry(fsc, path, started); | 870 | root = open_root_dentry(fsc, path, started); |
867 | if (IS_ERR(root)) { | 871 | if (IS_ERR(root)) { |
868 | err = PTR_ERR(root); | 872 | err = PTR_ERR(root); |
869 | goto out; | 873 | goto out; |
870 | } | 874 | } |
871 | fsc->sb->s_root = dget(root); | 875 | fsc->sb->s_root = dget(root); |
872 | first = 1; | ||
873 | |||
874 | err = ceph_fs_debugfs_init(fsc); | ||
875 | if (err < 0) | ||
876 | goto fail; | ||
877 | } else { | 876 | } else { |
878 | root = dget(fsc->sb->s_root); | 877 | root = dget(fsc->sb->s_root); |
879 | } | 878 | } |
@@ -883,11 +882,6 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc) | |||
883 | mutex_unlock(&fsc->client->mount_mutex); | 882 | mutex_unlock(&fsc->client->mount_mutex); |
884 | return root; | 883 | return root; |
885 | 884 | ||
886 | fail: | ||
887 | if (first) { | ||
888 | dput(fsc->sb->s_root); | ||
889 | fsc->sb->s_root = NULL; | ||
890 | } | ||
891 | out: | 885 | out: |
892 | mutex_unlock(&fsc->client->mount_mutex); | 886 | mutex_unlock(&fsc->client->mount_mutex); |
893 | return ERR_PTR(err); | 887 | return ERR_PTR(err); |