diff options
author | Yan, Zheng <zyan@redhat.com> | 2016-07-07 23:25:38 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2016-07-27 21:00:40 -0400 |
commit | 430afbadd6c885557ef2fb8c454bd5bba23a9850 (patch) | |
tree | 68aea0fc952a0a928ff6d409423d970a6057ddc6 /fs/ceph | |
parent | 0cabbd94ff52c4803fc0ad9ad0ad5e43df493ab0 (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.c | 87 | ||||
-rw-r--r-- | fs/ceph/mds_client.h | 7 | ||||
-rw-r--r-- | fs/ceph/super.c | 38 | ||||
-rw-r--r-- | fs/ceph/super.h | 2 |
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 | ||
3691 | void 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; | ||
3757 | bad: | ||
3758 | pr_err("error decoding fsmap\n"); | ||
3759 | err_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 | */ |
3690 | void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc, struct ceph_msg *msg) | 3770 | void 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 | ||
422 | extern void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc, | 423 | extern void ceph_mdsc_handle_mdsmap(struct ceph_mds_client *mdsc, |
423 | struct ceph_msg *msg); | 424 | struct ceph_msg *msg); |
425 | extern void ceph_mdsc_handle_fsmap(struct ceph_mds_client *mdsc, | ||
426 | struct ceph_msg *msg); | ||
424 | 427 | ||
425 | extern struct ceph_mds_session * | 428 | extern struct ceph_mds_session * |
426 | ceph_mdsc_open_export_target_session(struct ceph_mds_client *mdsc, int target); | 429 | ceph_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 | */ |
110 | enum { | 110 | enum { |
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 | ||
146 | static match_table_t fsopt_tokens = { | 146 | static 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 | ||