]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/ceph/super.c
Merge branches 'acpica-fixes', 'acpi-pci-fixes' and 'acpi-debug-fixes'
[karo-tx-linux.git] / fs / ceph / super.c
index f12d5e2955c223c35145bdf550d5669b823a14bc..91e02481ce06843cb231580458ebd3dc4ad7d111 100644 (file)
@@ -108,6 +108,7 @@ static int ceph_sync_fs(struct super_block *sb, int wait)
  * mount options
  */
 enum {
+       Opt_mds_namespace,
        Opt_wsize,
        Opt_rsize,
        Opt_rasize,
@@ -143,6 +144,7 @@ enum {
 };
 
 static match_table_t fsopt_tokens = {
+       {Opt_mds_namespace, "mds_namespace=%d"},
        {Opt_wsize, "wsize=%d"},
        {Opt_rsize, "rsize=%d"},
        {Opt_rasize, "rasize=%d"},
@@ -212,6 +214,9 @@ static int parse_fsopt_token(char *c, void *private)
                break;
 
                /* misc */
+       case Opt_mds_namespace:
+               fsopt->mds_namespace = intval;
+               break;
        case Opt_wsize:
                fsopt->wsize = intval;
                break;
@@ -297,6 +302,7 @@ static void destroy_mount_options(struct ceph_mount_options *args)
 {
        dout("destroy_mount_options %p\n", args);
        kfree(args->snapdir_name);
+       kfree(args->server_path);
        kfree(args);
 }
 
@@ -328,14 +334,17 @@ static int compare_mount_options(struct ceph_mount_options *new_fsopt,
        if (ret)
                return ret;
 
+       ret = strcmp_null(fsopt1->server_path, fsopt2->server_path);
+       if (ret)
+               return ret;
+
        return ceph_compare_options(new_opt, fsc->client);
 }
 
 static int parse_mount_options(struct ceph_mount_options **pfsopt,
                               struct ceph_options **popt,
                               int flags, char *options,
-                              const char *dev_name,
-                              const char **path)
+                              const char *dev_name)
 {
        struct ceph_mount_options *fsopt;
        const char *dev_name_end;
@@ -367,6 +376,7 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt,
        fsopt->max_readdir = CEPH_MAX_READDIR_DEFAULT;
        fsopt->max_readdir_bytes = CEPH_MAX_READDIR_BYTES_DEFAULT;
        fsopt->congestion_kb = default_congestion_kb();
+       fsopt->mds_namespace = CEPH_FS_CLUSTER_ID_NONE;
 
        /*
         * Distinguish the server list from the path in "dev_name".
@@ -380,12 +390,13 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt,
         */
        dev_name_end = strchr(dev_name, '/');
        if (dev_name_end) {
-               /* skip over leading '/' for path */
-               *path = dev_name_end + 1;
+               fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL);
+               if (!fsopt->server_path) {
+                       err = -ENOMEM;
+                       goto out;
+               }
        } else {
-               /* path is empty */
                dev_name_end = dev_name + strlen(dev_name);
-               *path = dev_name_end;
        }
        err = -EINVAL;
        dev_name_end--;         /* back up to ':' separator */
@@ -395,7 +406,8 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt,
                goto out;
        }
        dout("device name '%.*s'\n", (int)(dev_name_end - dev_name), dev_name);
-       dout("server path '%s'\n", *path);
+       if (fsopt->server_path)
+               dout("server path '%s'\n", fsopt->server_path);
 
        *popt = ceph_parse_options(options, dev_name, dev_name_end,
                                 parse_fsopt_token, (void *)fsopt);
@@ -457,6 +469,8 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root)
                seq_puts(m, ",noacl");
 #endif
 
+       if (fsopt->mds_namespace != CEPH_FS_CLUSTER_ID_NONE)
+               seq_printf(m, ",mds_namespace=%d", fsopt->mds_namespace);
        if (fsopt->wsize)
                seq_printf(m, ",wsize=%d", fsopt->wsize);
        if (fsopt->rsize != CEPH_RSIZE_DEFAULT)
@@ -511,9 +525,8 @@ static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt,
 {
        struct ceph_fs_client *fsc;
        const u64 supported_features =
-               CEPH_FEATURE_FLOCK |
-               CEPH_FEATURE_DIRLAYOUTHASH |
-               CEPH_FEATURE_MDS_INLINE_DATA;
+               CEPH_FEATURE_FLOCK | CEPH_FEATURE_DIRLAYOUTHASH |
+               CEPH_FEATURE_MDSENC | CEPH_FEATURE_MDS_INLINE_DATA;
        const u64 required_features = 0;
        int page_count;
        size_t size;
@@ -530,6 +543,7 @@ static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt,
                goto fail;
        }
        fsc->client->extra_mon_dispatch = extra_mon_dispatch;
+       fsc->client->monc.fs_cluster_id = fsopt->mds_namespace;
        ceph_monc_want_map(&fsc->client->monc, CEPH_SUB_MDSMAP, 0, true);
 
        fsc->mount_options = fsopt;
@@ -785,8 +799,7 @@ out:
 /*
  * mount: join the ceph cluster, and open root directory.
  */
-static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc,
-                     const char *path)
+static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc)
 {
        int err;
        unsigned long started = jiffies;  /* note the start time */
@@ -815,11 +828,12 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc,
                        goto fail;
        }
 
-       if (path[0] == 0) {
+       if (!fsc->mount_options->server_path) {
                root = fsc->sb->s_root;
                dget(root);
        } else {
-               dout("mount opening base mountpoint\n");
+               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);
@@ -935,7 +949,6 @@ static struct dentry *ceph_mount(struct file_system_type *fs_type,
        struct dentry *res;
        int err;
        int (*compare_super)(struct super_block *, void *) = ceph_compare_super;
-       const char *path = NULL;
        struct ceph_mount_options *fsopt = NULL;
        struct ceph_options *opt = NULL;
 
@@ -944,7 +957,7 @@ static struct dentry *ceph_mount(struct file_system_type *fs_type,
 #ifdef CONFIG_CEPH_FS_POSIX_ACL
        flags |= MS_POSIXACL;
 #endif
-       err = parse_mount_options(&fsopt, &opt, flags, data, dev_name, &path);
+       err = parse_mount_options(&fsopt, &opt, flags, data, dev_name);
        if (err < 0) {
                res = ERR_PTR(err);
                goto out_final;
@@ -987,7 +1000,7 @@ static struct dentry *ceph_mount(struct file_system_type *fs_type,
                }
        }
 
-       res = ceph_real_mount(fsc, path);
+       res = ceph_real_mount(fsc);
        if (IS_ERR(res))
                goto out_splat;
        dout("root %p inode %p ino %llx.%llx\n", res,