aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2016-09-14 02:53:05 -0400
committerIlya Dryomov <idryomov@gmail.com>2016-10-03 10:13:50 -0400
commitce2728aaa82bbebae7d20345324af3f0f49eeb20 (patch)
tree731e14ae717753dbaf2771956266a1f36a6d856a
parentdb4a63aab43b2040292b2023512864702b5f9799 (diff)
ceph: avoid accessing / when mounting a subpath
Accessing / causes failuire if the client has caps that restrict path Signed-off-by: Yan, Zheng <zyan@redhat.com>
-rw-r--r--fs/ceph/super.c49
1 files changed, 20 insertions, 29 deletions
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index e247f6f0feb7..a29ffce98187 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -396,10 +396,12 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt,
396 */ 396 */
397 dev_name_end = strchr(dev_name, '/'); 397 dev_name_end = strchr(dev_name, '/');
398 if (dev_name_end) { 398 if (dev_name_end) {
399 fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL); 399 if (strlen(dev_name_end) > 1) {
400 if (!fsopt->server_path) { 400 fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL);
401 err = -ENOMEM; 401 if (!fsopt->server_path) {
402 goto out; 402 err = -ENOMEM;
403 goto out;
404 }
403 } 405 }
404 } else { 406 } else {
405 dev_name_end = dev_name + strlen(dev_name); 407 dev_name_end = dev_name + strlen(dev_name);
@@ -788,15 +790,10 @@ static struct dentry *open_root_dentry(struct ceph_fs_client *fsc,
788 struct inode *inode = req->r_target_inode; 790 struct inode *inode = req->r_target_inode;
789 req->r_target_inode = NULL; 791 req->r_target_inode = NULL;
790 dout("open_root_inode success\n"); 792 dout("open_root_inode success\n");
791 if (ceph_ino(inode) == CEPH_INO_ROOT && 793 root = d_make_root(inode);
792 fsc->sb->s_root == NULL) { 794 if (!root) {
793 root = d_make_root(inode); 795 root = ERR_PTR(-ENOMEM);
794 if (!root) { 796 goto out;
795 root = ERR_PTR(-ENOMEM);
796 goto out;
797 }
798 } else {
799 root = d_obtain_root(inode);
800 } 797 }
801 ceph_init_dentry(root); 798 ceph_init_dentry(root);
802 dout("open_root_inode success, root dentry is %p\n", root); 799 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 mutex_lock(&fsc->client->mount_mutex); 822 mutex_lock(&fsc->client->mount_mutex);
826 823
827 if (!fsc->sb->s_root) { 824 if (!fsc->sb->s_root) {
825 const char *path;
828 err = __ceph_open_session(fsc->client, started); 826 err = __ceph_open_session(fsc->client, started);
829 if (err < 0) 827 if (err < 0)
830 goto out; 828 goto out;
831 829
832 dout("mount opening root\n"); 830 if (!fsc->mount_options->server_path) {
833 root = open_root_dentry(fsc, "", started); 831 path = "";
832 dout("mount opening path \\t\n");
833 } else {
834 path = fsc->mount_options->server_path + 1;
835 dout("mount opening path %s\n", path);
836 }
837 root = open_root_dentry(fsc, path, started);
834 if (IS_ERR(root)) { 838 if (IS_ERR(root)) {
835 err = PTR_ERR(root); 839 err = PTR_ERR(root);
836 goto out; 840 goto out;
837 } 841 }
838 fsc->sb->s_root = root; 842 fsc->sb->s_root = dget(root);
839 first = 1; 843 first = 1;
840 844
841 err = ceph_fs_debugfs_init(fsc); 845 err = ceph_fs_debugfs_init(fsc);
@@ -843,19 +847,6 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc)
843 goto fail; 847 goto fail;
844 } 848 }
845 849
846 if (!fsc->mount_options->server_path) {
847 root = fsc->sb->s_root;
848 dget(root);
849 } else {
850 const char *path = fsc->mount_options->server_path + 1;
851 dout("mount opening path %s\n", path);
852 root = open_root_dentry(fsc, path, started);
853 if (IS_ERR(root)) {
854 err = PTR_ERR(root);
855 goto fail;
856 }
857 }
858
859 fsc->mount_state = CEPH_MOUNT_MOUNTED; 850 fsc->mount_state = CEPH_MOUNT_MOUNTED;
860 dout("mount success\n"); 851 dout("mount success\n");
861 mutex_unlock(&fsc->client->mount_mutex); 852 mutex_unlock(&fsc->client->mount_mutex);