Commit ce2728aa authored by Yan, Zheng's avatar Yan, Zheng Committed by Ilya Dryomov

ceph: avoid accessing / when mounting a subpath

Accessing / causes failuire if the client has caps that restrict path
Signed-off-by: default avatarYan, Zheng <zyan@redhat.com>
parent db4a63aa
...@@ -396,10 +396,12 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt, ...@@ -396,10 +396,12 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt,
*/ */
dev_name_end = strchr(dev_name, '/'); dev_name_end = strchr(dev_name, '/');
if (dev_name_end) { if (dev_name_end) {
fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL); if (strlen(dev_name_end) > 1) {
if (!fsopt->server_path) { fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL);
err = -ENOMEM; if (!fsopt->server_path) {
goto out; err = -ENOMEM;
goto out;
}
} }
} else { } else {
dev_name_end = dev_name + strlen(dev_name); dev_name_end = dev_name + strlen(dev_name);
...@@ -788,15 +790,10 @@ static struct dentry *open_root_dentry(struct ceph_fs_client *fsc, ...@@ -788,15 +790,10 @@ static struct dentry *open_root_dentry(struct ceph_fs_client *fsc,
struct inode *inode = req->r_target_inode; struct inode *inode = req->r_target_inode;
req->r_target_inode = NULL; req->r_target_inode = NULL;
dout("open_root_inode success\n"); dout("open_root_inode success\n");
if (ceph_ino(inode) == CEPH_INO_ROOT && root = d_make_root(inode);
fsc->sb->s_root == NULL) { if (!root) {
root = d_make_root(inode); root = ERR_PTR(-ENOMEM);
if (!root) { goto out;
root = ERR_PTR(-ENOMEM);
goto out;
}
} else {
root = d_obtain_root(inode);
} }
ceph_init_dentry(root); ceph_init_dentry(root);
dout("open_root_inode success, root dentry is %p\n", root); dout("open_root_inode success, root dentry is %p\n", root);
...@@ -825,17 +822,24 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc) ...@@ -825,17 +822,24 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc)
mutex_lock(&fsc->client->mount_mutex); mutex_lock(&fsc->client->mount_mutex);
if (!fsc->sb->s_root) { if (!fsc->sb->s_root) {
const char *path;
err = __ceph_open_session(fsc->client, started); err = __ceph_open_session(fsc->client, started);
if (err < 0) if (err < 0)
goto out; goto out;
dout("mount opening root\n"); if (!fsc->mount_options->server_path) {
root = open_root_dentry(fsc, "", started); path = "";
dout("mount opening path \\t\n");
} else {
path = fsc->mount_options->server_path + 1;
dout("mount opening path %s\n", path);
}
root = open_root_dentry(fsc, path, started);
if (IS_ERR(root)) { if (IS_ERR(root)) {
err = PTR_ERR(root); err = PTR_ERR(root);
goto out; goto out;
} }
fsc->sb->s_root = root; fsc->sb->s_root = dget(root);
first = 1; first = 1;
err = ceph_fs_debugfs_init(fsc); err = ceph_fs_debugfs_init(fsc);
...@@ -843,19 +847,6 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc) ...@@ -843,19 +847,6 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc)
goto fail; goto fail;
} }
if (!fsc->mount_options->server_path) {
root = fsc->sb->s_root;
dget(root);
} else {
const char *path = fsc->mount_options->server_path + 1;
dout("mount opening path %s\n", path);
root = open_root_dentry(fsc, path, started);
if (IS_ERR(root)) {
err = PTR_ERR(root);
goto fail;
}
}
fsc->mount_state = CEPH_MOUNT_MOUNTED; fsc->mount_state = CEPH_MOUNT_MOUNTED;
dout("mount success\n"); dout("mount success\n");
mutex_unlock(&fsc->client->mount_mutex); mutex_unlock(&fsc->client->mount_mutex);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment