summaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2016-07-07 23:25:38 -0400
committerIlya Dryomov <idryomov@gmail.com>2016-07-27 21:00:40 -0400
commit430afbadd6c885557ef2fb8c454bd5bba23a9850 (patch)
tree68aea0fc952a0a928ff6d409423d970a6057ddc6 /fs/ceph
parent0cabbd94ff52c4803fc0ad9ad0ad5e43df493ab0 (diff)
ceph: mount non-default filesystem by name
To mount non-default filesytem, user currently needs to provide mds namespace ID. This is inconvenience. This patch makes user be able to mount filesystem by name. If user wants to mount non-default filesystem. Client first subscribes to fsmap.user. Subscribe to mdsmap.<ID> after getting ID of filesystem. Signed-off-by: Yan, Zheng <zyan@redhat.com>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/mds_client.c87
-rw-r--r--fs/ceph/mds_client.h7
-rw-r--r--fs/ceph/super.c38
-rw-r--r--fs/ceph/super.h2
4 files changed, 117 insertions, 17 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 78a3495a11be..e555745883da 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -2166,6 +2166,11 @@ static int __do_request(struct ceph_mds_client *mdsc,
2166 mds = __choose_mds(mdsc, req); 2166 mds = __choose_mds(mdsc, req);
2167 if (mds < 0 || 2167 if (mds < 0 ||
2168 ceph_mdsmap_get_state(mdsc->mdsmap, mds) < CEPH_MDS_STATE_ACTIVE) { 2168 ceph_mdsmap_get_state(mdsc->mdsmap, mds) < CEPH_MDS_STATE_ACTIVE) {
2169 if (mdsc->mdsmap_err) {
2170 err = mdsc->mdsmap_err;
2171 dout("do_request mdsmap err %d\n", err);
2172 goto finish;
2173 }
2169 dout("do_request no mds or not active, waiting for map\n"); 2174 dout("do_request no mds or not active, waiting for map\n");
2170 list_add(&req->r_wait, &mdsc->waiting_for_map); 2175 list_add(&req->r_wait, &mdsc->waiting_for_map);
2171 goto out; 2176 goto out;
@@ -3683,11 +3688,86 @@ void ceph_mdsc_destroy(struct ceph_fs_client *fsc)
3683 dout("mdsc_destroy %p done\n", mdsc); 3688 dout("mdsc_destroy %p done\n", mdsc);
3684} 3689}
3685 3690
3691void ceph_mdsc_handle_fsmap(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
3692{
3693 struct ceph_fs_client *fsc = mdsc->fsc;
3694 const char *mds_namespace = fsc->mount_options->mds_namespace;
3695 void *p = msg->front.iov_base;
3696 void *end = p + msg->front.iov_len;
3697 u32 epoch;
3698 u32 map_len;
3699 u32 num_fs;
3700 u32 mount_fscid = (u32)-1;
3701 u8 struct_v, struct_cv;
3702 int err = -EINVAL;
3703
3704 ceph_decode_need(&p, end, sizeof(u32), bad);
3705 epoch = ceph_decode_32(&p);
3706
3707 dout("handle_fsmap epoch %u\n", epoch);
3708
3709 ceph_decode_need(&p, end, 2 + sizeof(u32), bad);
3710 struct_v = ceph_decode_8(&p);
3711 struct_cv = ceph_decode_8(&p);
3712 map_len = ceph_decode_32(&p);
3713
3714 ceph_decode_need(&p, end, sizeof(u32) * 3, bad);
3715 p += sizeof(u32) * 2; /* skip epoch and legacy_client_fscid */
3716
3717 num_fs = ceph_decode_32(&p);
3718 while (num_fs-- > 0) {
3719 void *info_p, *info_end;
3720 u32 info_len;
3721 u8 info_v, info_cv;
3722 u32 fscid, namelen;
3723
3724 ceph_decode_need(&p, end, 2 + sizeof(u32), bad);
3725 info_v = ceph_decode_8(&p);
3726 info_cv = ceph_decode_8(&p);
3727 info_len = ceph_decode_32(&p);
3728 ceph_decode_need(&p, end, info_len, bad);
3729 info_p = p;
3730 info_end = p + info_len;
3731 p = info_end;
3732
3733 ceph_decode_need(&info_p, info_end, sizeof(u32) * 2, bad);
3734 fscid = ceph_decode_32(&info_p);
3735 namelen = ceph_decode_32(&info_p);
3736 ceph_decode_need(&info_p, info_end, namelen, bad);
3737
3738 if (mds_namespace &&
3739 strlen(mds_namespace) == namelen &&
3740 !strncmp(mds_namespace, (char *)info_p, namelen)) {
3741 mount_fscid = fscid;
3742 break;
3743 }
3744 }
3745
3746 ceph_monc_got_map(&fsc->client->monc, CEPH_SUB_FSMAP, epoch);
3747 if (mount_fscid != (u32)-1) {
3748 fsc->client->monc.fs_cluster_id = mount_fscid;
3749 ceph_monc_want_map(&fsc->client->monc, CEPH_SUB_MDSMAP,
3750 0, true);
3751 ceph_monc_renew_subs(&fsc->client->monc);
3752 } else {
3753 err = -ENOENT;
3754 goto err_out;
3755 }
3756 return;
3757bad:
3758 pr_err("error decoding fsmap\n");
3759err_out:
3760 mutex_lock(&mdsc->mutex);
3761 mdsc->mdsmap_err = -ENOENT;
3762 __wake_requests(mdsc, &mdsc->waiting_for_map);
3763 mutex_unlock(&mdsc->mutex);
3764 return;
3765}
3686 3766
3687/* 3767/*
3688 * handle mds map update. 3768 * handle mds map update.
3689 */ 3769 */
3690void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc, struct ceph_msg *msg) 3770void ceph_mdsc_handle_mdsmap(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
3691{ 3771{
3692 u32 epoch; 3772 u32 epoch;
3693 u32 maplen; 3773 u32 maplen;
@@ -3794,7 +3874,10 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
3794 3874
3795 switch (type) { 3875 switch (type) {
3796 case CEPH_MSG_MDS_MAP: 3876 case CEPH_MSG_MDS_MAP:
3797 ceph_mdsc_handle_map(mdsc, msg); 3877 ceph_mdsc_handle_mdsmap(mdsc, msg);
3878 break;
3879 case CEPH_MSG_FS_MAP_USER:
3880 ceph_mdsc_handle_fsmap(mdsc, msg);
3798 break; 3881 break;
3799 case CEPH_MSG_CLIENT_SESSION: 3882 case CEPH_MSG_CLIENT_SESSION:
3800 handle_session(s, msg); 3883 handle_session(s, msg);
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
index 9dd2c82379f8..3c154b8d49bf 100644
--- a/fs/ceph/mds_client.h
+++ b/fs/ceph/mds_client.h
@@ -293,6 +293,7 @@ struct ceph_mds_client {
293 struct completion safe_umount_waiters; 293 struct completion safe_umount_waiters;
294 wait_queue_head_t session_close_wq; 294 wait_queue_head_t session_close_wq;
295 struct list_head waiting_for_map; 295 struct list_head waiting_for_map;
296 int mdsmap_err;
296 297
297 struct ceph_mds_session **sessions; /* NULL for mds if no session */ 298 struct ceph_mds_session **sessions; /* NULL for mds if no session */
298 atomic_t num_sessions; 299 atomic_t num_sessions;
@@ -419,8 +420,10 @@ extern void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session,
419 struct dentry *dentry, char action, 420 struct dentry *dentry, char action,
420 u32 seq); 421 u32 seq);
421 422
422extern void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc, 423extern void ceph_mdsc_handle_mdsmap(struct ceph_mds_client *mdsc,
423 struct ceph_msg *msg); 424 struct ceph_msg *msg);
425extern void ceph_mdsc_handle_fsmap(struct ceph_mds_client *mdsc,
426 struct ceph_msg *msg);
424 427
425extern struct ceph_mds_session * 428extern struct ceph_mds_session *
426ceph_mdsc_open_export_target_session(struct ceph_mds_client *mdsc, int target); 429ceph_mdsc_open_export_target_session(struct ceph_mds_client *mdsc, int target);
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index a5b2275e1573..7736a931376e 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -108,7 +108,6 @@ static int ceph_sync_fs(struct super_block *sb, int wait)
108 * mount options 108 * mount options
109 */ 109 */
110enum { 110enum {
111 Opt_mds_namespace,
112 Opt_wsize, 111 Opt_wsize,
113 Opt_rsize, 112 Opt_rsize,
114 Opt_rasize, 113 Opt_rasize,
@@ -121,6 +120,7 @@ enum {
121 Opt_last_int, 120 Opt_last_int,
122 /* int args above */ 121 /* int args above */
123 Opt_snapdirname, 122 Opt_snapdirname,
123 Opt_mds_namespace,
124 Opt_last_string, 124 Opt_last_string,
125 /* string args above */ 125 /* string args above */
126 Opt_dirstat, 126 Opt_dirstat,
@@ -144,7 +144,6 @@ enum {
144}; 144};
145 145
146static match_table_t fsopt_tokens = { 146static match_table_t fsopt_tokens = {
147 {Opt_mds_namespace, "mds_namespace=%d"},
148 {Opt_wsize, "wsize=%d"}, 147 {Opt_wsize, "wsize=%d"},
149 {Opt_rsize, "rsize=%d"}, 148 {Opt_rsize, "rsize=%d"},
150 {Opt_rasize, "rasize=%d"}, 149 {Opt_rasize, "rasize=%d"},
@@ -156,6 +155,7 @@ static match_table_t fsopt_tokens = {
156 {Opt_congestion_kb, "write_congestion_kb=%d"}, 155 {Opt_congestion_kb, "write_congestion_kb=%d"},
157 /* int args above */ 156 /* int args above */
158 {Opt_snapdirname, "snapdirname=%s"}, 157 {Opt_snapdirname, "snapdirname=%s"},
158 {Opt_mds_namespace, "mds_namespace=%s"},
159 /* string args above */ 159 /* string args above */
160 {Opt_dirstat, "dirstat"}, 160 {Opt_dirstat, "dirstat"},
161 {Opt_nodirstat, "nodirstat"}, 161 {Opt_nodirstat, "nodirstat"},
@@ -212,11 +212,14 @@ static int parse_fsopt_token(char *c, void *private)
212 if (!fsopt->snapdir_name) 212 if (!fsopt->snapdir_name)
213 return -ENOMEM; 213 return -ENOMEM;
214 break; 214 break;
215
216 /* misc */
217 case Opt_mds_namespace: 215 case Opt_mds_namespace:
218 fsopt->mds_namespace = intval; 216 fsopt->mds_namespace = kstrndup(argstr[0].from,
217 argstr[0].to-argstr[0].from,
218 GFP_KERNEL);
219 if (!fsopt->mds_namespace)
220 return -ENOMEM;
219 break; 221 break;
222 /* misc */
220 case Opt_wsize: 223 case Opt_wsize:
221 fsopt->wsize = intval; 224 fsopt->wsize = intval;
222 break; 225 break;
@@ -302,6 +305,7 @@ static void destroy_mount_options(struct ceph_mount_options *args)
302{ 305{
303 dout("destroy_mount_options %p\n", args); 306 dout("destroy_mount_options %p\n", args);
304 kfree(args->snapdir_name); 307 kfree(args->snapdir_name);
308 kfree(args->mds_namespace);
305 kfree(args->server_path); 309 kfree(args->server_path);
306 kfree(args); 310 kfree(args);
307} 311}
@@ -333,6 +337,9 @@ static int compare_mount_options(struct ceph_mount_options *new_fsopt,
333 ret = strcmp_null(fsopt1->snapdir_name, fsopt2->snapdir_name); 337 ret = strcmp_null(fsopt1->snapdir_name, fsopt2->snapdir_name);
334 if (ret) 338 if (ret)
335 return ret; 339 return ret;
340 ret = strcmp_null(fsopt1->mds_namespace, fsopt2->mds_namespace);
341 if (ret)
342 return ret;
336 343
337 ret = strcmp_null(fsopt1->server_path, fsopt2->server_path); 344 ret = strcmp_null(fsopt1->server_path, fsopt2->server_path);
338 if (ret) 345 if (ret)
@@ -376,7 +383,6 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt,
376 fsopt->max_readdir = CEPH_MAX_READDIR_DEFAULT; 383 fsopt->max_readdir = CEPH_MAX_READDIR_DEFAULT;
377 fsopt->max_readdir_bytes = CEPH_MAX_READDIR_BYTES_DEFAULT; 384 fsopt->max_readdir_bytes = CEPH_MAX_READDIR_BYTES_DEFAULT;
378 fsopt->congestion_kb = default_congestion_kb(); 385 fsopt->congestion_kb = default_congestion_kb();
379 fsopt->mds_namespace = CEPH_FS_CLUSTER_ID_NONE;
380 386
381 /* 387 /*
382 * Distinguish the server list from the path in "dev_name". 388 * Distinguish the server list from the path in "dev_name".
@@ -469,8 +475,8 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root)
469 seq_puts(m, ",noacl"); 475 seq_puts(m, ",noacl");
470#endif 476#endif
471 477
472 if (fsopt->mds_namespace != CEPH_FS_CLUSTER_ID_NONE) 478 if (fsopt->mds_namespace)
473 seq_printf(m, ",mds_namespace=%d", fsopt->mds_namespace); 479 seq_printf(m, ",mds_namespace=%s", fsopt->mds_namespace);
474 if (fsopt->wsize) 480 if (fsopt->wsize)
475 seq_printf(m, ",wsize=%d", fsopt->wsize); 481 seq_printf(m, ",wsize=%d", fsopt->wsize);
476 if (fsopt->rsize != CEPH_RSIZE_DEFAULT) 482 if (fsopt->rsize != CEPH_RSIZE_DEFAULT)
@@ -509,9 +515,11 @@ static int extra_mon_dispatch(struct ceph_client *client, struct ceph_msg *msg)
509 515
510 switch (type) { 516 switch (type) {
511 case CEPH_MSG_MDS_MAP: 517 case CEPH_MSG_MDS_MAP:
512 ceph_mdsc_handle_map(fsc->mdsc, msg); 518 ceph_mdsc_handle_mdsmap(fsc->mdsc, msg);
519 return 0;
520 case CEPH_MSG_FS_MAP_USER:
521 ceph_mdsc_handle_fsmap(fsc->mdsc, msg);
513 return 0; 522 return 0;
514
515 default: 523 default:
516 return -1; 524 return -1;
517 } 525 }
@@ -543,8 +551,14 @@ static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt,
543 goto fail; 551 goto fail;
544 } 552 }
545 fsc->client->extra_mon_dispatch = extra_mon_dispatch; 553 fsc->client->extra_mon_dispatch = extra_mon_dispatch;
546 fsc->client->monc.fs_cluster_id = fsopt->mds_namespace; 554
547 ceph_monc_want_map(&fsc->client->monc, CEPH_SUB_MDSMAP, 0, true); 555 if (fsopt->mds_namespace == NULL) {
556 ceph_monc_want_map(&fsc->client->monc, CEPH_SUB_MDSMAP,
557 0, true);
558 } else {
559 ceph_monc_want_map(&fsc->client->monc, CEPH_SUB_FSMAP,
560 0, false);
561 }
548 562
549 fsc->mount_options = fsopt; 563 fsc->mount_options = fsopt;
550 564
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 5aa3158e8611..9e82e29f86a1 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -62,7 +62,6 @@ struct ceph_mount_options {
62 int cap_release_safety; 62 int cap_release_safety;
63 int max_readdir; /* max readdir result (entires) */ 63 int max_readdir; /* max readdir result (entires) */
64 int max_readdir_bytes; /* max readdir result (bytes) */ 64 int max_readdir_bytes; /* max readdir result (bytes) */
65 int mds_namespace;
66 65
67 /* 66 /*
68 * everything above this point can be memcmp'd; everything below 67 * everything above this point can be memcmp'd; everything below
@@ -70,6 +69,7 @@ struct ceph_mount_options {
70 */ 69 */
71 70
72 char *snapdir_name; /* default ".snap" */ 71 char *snapdir_name; /* default ".snap" */
72 char *mds_namespace; /* default NULL */
73 char *server_path; /* default "/" */ 73 char *server_path; /* default "/" */
74}; 74};
75 75