diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ceph/ceph_common.c | 2 | ||||
-rw-r--r-- | net/ceph/debugfs.c | 8 | ||||
-rw-r--r-- | net/ceph/mon_client.c | 150 |
3 files changed, 153 insertions, 7 deletions
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index 67d7721d237e..1675021d8c12 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c | |||
@@ -72,6 +72,8 @@ const char *ceph_msg_type_name(int type) | |||
72 | case CEPH_MSG_MON_SUBSCRIBE_ACK: return "mon_subscribe_ack"; | 72 | case CEPH_MSG_MON_SUBSCRIBE_ACK: return "mon_subscribe_ack"; |
73 | case CEPH_MSG_STATFS: return "statfs"; | 73 | case CEPH_MSG_STATFS: return "statfs"; |
74 | case CEPH_MSG_STATFS_REPLY: return "statfs_reply"; | 74 | case CEPH_MSG_STATFS_REPLY: return "statfs_reply"; |
75 | case CEPH_MSG_MON_GET_VERSION: return "mon_get_version"; | ||
76 | case CEPH_MSG_MON_GET_VERSION_REPLY: return "mon_get_version_reply"; | ||
75 | case CEPH_MSG_MDS_MAP: return "mds_map"; | 77 | case CEPH_MSG_MDS_MAP: return "mds_map"; |
76 | case CEPH_MSG_CLIENT_SESSION: return "client_session"; | 78 | case CEPH_MSG_CLIENT_SESSION: return "client_session"; |
77 | case CEPH_MSG_CLIENT_RECONNECT: return "client_reconnect"; | 79 | case CEPH_MSG_CLIENT_RECONNECT: return "client_reconnect"; |
diff --git a/net/ceph/debugfs.c b/net/ceph/debugfs.c index 10421a4b76f8..d1a62c69a9f4 100644 --- a/net/ceph/debugfs.c +++ b/net/ceph/debugfs.c | |||
@@ -126,9 +126,13 @@ static int monc_show(struct seq_file *s, void *p) | |||
126 | req = rb_entry(rp, struct ceph_mon_generic_request, node); | 126 | req = rb_entry(rp, struct ceph_mon_generic_request, node); |
127 | op = le16_to_cpu(req->request->hdr.type); | 127 | op = le16_to_cpu(req->request->hdr.type); |
128 | if (op == CEPH_MSG_STATFS) | 128 | if (op == CEPH_MSG_STATFS) |
129 | seq_printf(s, "%lld statfs\n", req->tid); | 129 | seq_printf(s, "%llu statfs\n", req->tid); |
130 | else if (op == CEPH_MSG_POOLOP) | ||
131 | seq_printf(s, "%llu poolop\n", req->tid); | ||
132 | else if (op == CEPH_MSG_MON_GET_VERSION) | ||
133 | seq_printf(s, "%llu mon_get_version", req->tid); | ||
130 | else | 134 | else |
131 | seq_printf(s, "%lld unknown\n", req->tid); | 135 | seq_printf(s, "%llu unknown\n", req->tid); |
132 | } | 136 | } |
133 | 137 | ||
134 | mutex_unlock(&monc->mutex); | 138 | mutex_unlock(&monc->mutex); |
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c index 2ac9ef35110b..067d3af2eaf6 100644 --- a/net/ceph/mon_client.c +++ b/net/ceph/mon_client.c | |||
@@ -296,6 +296,33 @@ void ceph_monc_request_next_osdmap(struct ceph_mon_client *monc) | |||
296 | __send_subscribe(monc); | 296 | __send_subscribe(monc); |
297 | mutex_unlock(&monc->mutex); | 297 | mutex_unlock(&monc->mutex); |
298 | } | 298 | } |
299 | EXPORT_SYMBOL(ceph_monc_request_next_osdmap); | ||
300 | |||
301 | int ceph_monc_wait_osdmap(struct ceph_mon_client *monc, u32 epoch, | ||
302 | unsigned long timeout) | ||
303 | { | ||
304 | unsigned long started = jiffies; | ||
305 | int ret; | ||
306 | |||
307 | mutex_lock(&monc->mutex); | ||
308 | while (monc->have_osdmap < epoch) { | ||
309 | mutex_unlock(&monc->mutex); | ||
310 | |||
311 | if (timeout != 0 && time_after_eq(jiffies, started + timeout)) | ||
312 | return -ETIMEDOUT; | ||
313 | |||
314 | ret = wait_event_interruptible_timeout(monc->client->auth_wq, | ||
315 | monc->have_osdmap >= epoch, timeout); | ||
316 | if (ret < 0) | ||
317 | return ret; | ||
318 | |||
319 | mutex_lock(&monc->mutex); | ||
320 | } | ||
321 | |||
322 | mutex_unlock(&monc->mutex); | ||
323 | return 0; | ||
324 | } | ||
325 | EXPORT_SYMBOL(ceph_monc_wait_osdmap); | ||
299 | 326 | ||
300 | /* | 327 | /* |
301 | * | 328 | * |
@@ -477,14 +504,13 @@ static struct ceph_msg *get_generic_reply(struct ceph_connection *con, | |||
477 | return m; | 504 | return m; |
478 | } | 505 | } |
479 | 506 | ||
480 | static int do_generic_request(struct ceph_mon_client *monc, | 507 | static int __do_generic_request(struct ceph_mon_client *monc, u64 tid, |
481 | struct ceph_mon_generic_request *req) | 508 | struct ceph_mon_generic_request *req) |
482 | { | 509 | { |
483 | int err; | 510 | int err; |
484 | 511 | ||
485 | /* register request */ | 512 | /* register request */ |
486 | mutex_lock(&monc->mutex); | 513 | req->tid = tid != 0 ? tid : ++monc->last_tid; |
487 | req->tid = ++monc->last_tid; | ||
488 | req->request->hdr.tid = cpu_to_le64(req->tid); | 514 | req->request->hdr.tid = cpu_to_le64(req->tid); |
489 | __insert_generic_request(monc, req); | 515 | __insert_generic_request(monc, req); |
490 | monc->num_generic_requests++; | 516 | monc->num_generic_requests++; |
@@ -496,13 +522,24 @@ static int do_generic_request(struct ceph_mon_client *monc, | |||
496 | mutex_lock(&monc->mutex); | 522 | mutex_lock(&monc->mutex); |
497 | rb_erase(&req->node, &monc->generic_request_tree); | 523 | rb_erase(&req->node, &monc->generic_request_tree); |
498 | monc->num_generic_requests--; | 524 | monc->num_generic_requests--; |
499 | mutex_unlock(&monc->mutex); | ||
500 | 525 | ||
501 | if (!err) | 526 | if (!err) |
502 | err = req->result; | 527 | err = req->result; |
503 | return err; | 528 | return err; |
504 | } | 529 | } |
505 | 530 | ||
531 | static int do_generic_request(struct ceph_mon_client *monc, | ||
532 | struct ceph_mon_generic_request *req) | ||
533 | { | ||
534 | int err; | ||
535 | |||
536 | mutex_lock(&monc->mutex); | ||
537 | err = __do_generic_request(monc, 0, req); | ||
538 | mutex_unlock(&monc->mutex); | ||
539 | |||
540 | return err; | ||
541 | } | ||
542 | |||
506 | /* | 543 | /* |
507 | * statfs | 544 | * statfs |
508 | */ | 545 | */ |
@@ -579,6 +616,96 @@ out: | |||
579 | } | 616 | } |
580 | EXPORT_SYMBOL(ceph_monc_do_statfs); | 617 | EXPORT_SYMBOL(ceph_monc_do_statfs); |
581 | 618 | ||
619 | static void handle_get_version_reply(struct ceph_mon_client *monc, | ||
620 | struct ceph_msg *msg) | ||
621 | { | ||
622 | struct ceph_mon_generic_request *req; | ||
623 | u64 tid = le64_to_cpu(msg->hdr.tid); | ||
624 | void *p = msg->front.iov_base; | ||
625 | void *end = p + msg->front_alloc_len; | ||
626 | u64 handle; | ||
627 | |||
628 | dout("%s %p tid %llu\n", __func__, msg, tid); | ||
629 | |||
630 | ceph_decode_need(&p, end, 2*sizeof(u64), bad); | ||
631 | handle = ceph_decode_64(&p); | ||
632 | if (tid != 0 && tid != handle) | ||
633 | goto bad; | ||
634 | |||
635 | mutex_lock(&monc->mutex); | ||
636 | req = __lookup_generic_req(monc, handle); | ||
637 | if (req) { | ||
638 | *(u64 *)req->buf = ceph_decode_64(&p); | ||
639 | req->result = 0; | ||
640 | get_generic_request(req); | ||
641 | } | ||
642 | mutex_unlock(&monc->mutex); | ||
643 | if (req) { | ||
644 | complete_all(&req->completion); | ||
645 | put_generic_request(req); | ||
646 | } | ||
647 | |||
648 | return; | ||
649 | bad: | ||
650 | pr_err("corrupt mon_get_version reply\n"); | ||
651 | ceph_msg_dump(msg); | ||
652 | } | ||
653 | |||
654 | /* | ||
655 | * Send MMonGetVersion and wait for the reply. | ||
656 | * | ||
657 | * @what: one of "mdsmap", "osdmap" or "monmap" | ||
658 | */ | ||
659 | int ceph_monc_do_get_version(struct ceph_mon_client *monc, const char *what, | ||
660 | u64 *newest) | ||
661 | { | ||
662 | struct ceph_mon_generic_request *req; | ||
663 | void *p, *end; | ||
664 | u64 tid; | ||
665 | int err; | ||
666 | |||
667 | req = kzalloc(sizeof(*req), GFP_NOFS); | ||
668 | if (!req) | ||
669 | return -ENOMEM; | ||
670 | |||
671 | kref_init(&req->kref); | ||
672 | req->buf = newest; | ||
673 | req->buf_len = sizeof(*newest); | ||
674 | init_completion(&req->completion); | ||
675 | |||
676 | req->request = ceph_msg_new(CEPH_MSG_MON_GET_VERSION, | ||
677 | sizeof(u64) + sizeof(u32) + strlen(what), | ||
678 | GFP_NOFS, true); | ||
679 | if (!req->request) { | ||
680 | err = -ENOMEM; | ||
681 | goto out; | ||
682 | } | ||
683 | |||
684 | req->reply = ceph_msg_new(CEPH_MSG_MON_GET_VERSION_REPLY, 1024, | ||
685 | GFP_NOFS, true); | ||
686 | if (!req->reply) { | ||
687 | err = -ENOMEM; | ||
688 | goto out; | ||
689 | } | ||
690 | |||
691 | p = req->request->front.iov_base; | ||
692 | end = p + req->request->front_alloc_len; | ||
693 | |||
694 | /* fill out request */ | ||
695 | mutex_lock(&monc->mutex); | ||
696 | tid = ++monc->last_tid; | ||
697 | ceph_encode_64(&p, tid); /* handle */ | ||
698 | ceph_encode_string(&p, end, what, strlen(what)); | ||
699 | |||
700 | err = __do_generic_request(monc, tid, req); | ||
701 | |||
702 | mutex_unlock(&monc->mutex); | ||
703 | out: | ||
704 | kref_put(&req->kref, release_generic_request); | ||
705 | return err; | ||
706 | } | ||
707 | EXPORT_SYMBOL(ceph_monc_do_get_version); | ||
708 | |||
582 | /* | 709 | /* |
583 | * pool ops | 710 | * pool ops |
584 | */ | 711 | */ |
@@ -981,6 +1108,10 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) | |||
981 | handle_statfs_reply(monc, msg); | 1108 | handle_statfs_reply(monc, msg); |
982 | break; | 1109 | break; |
983 | 1110 | ||
1111 | case CEPH_MSG_MON_GET_VERSION_REPLY: | ||
1112 | handle_get_version_reply(monc, msg); | ||
1113 | break; | ||
1114 | |||
984 | case CEPH_MSG_POOLOP_REPLY: | 1115 | case CEPH_MSG_POOLOP_REPLY: |
985 | handle_poolop_reply(monc, msg); | 1116 | handle_poolop_reply(monc, msg); |
986 | break; | 1117 | break; |
@@ -1029,6 +1160,15 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con, | |||
1029 | case CEPH_MSG_AUTH_REPLY: | 1160 | case CEPH_MSG_AUTH_REPLY: |
1030 | m = ceph_msg_get(monc->m_auth_reply); | 1161 | m = ceph_msg_get(monc->m_auth_reply); |
1031 | break; | 1162 | break; |
1163 | case CEPH_MSG_MON_GET_VERSION_REPLY: | ||
1164 | if (le64_to_cpu(hdr->tid) != 0) | ||
1165 | return get_generic_reply(con, hdr, skip); | ||
1166 | |||
1167 | /* | ||
1168 | * Older OSDs don't set reply tid even if the orignal | ||
1169 | * request had a non-zero tid. Workaround this weirdness | ||
1170 | * by falling through to the allocate case. | ||
1171 | */ | ||
1032 | case CEPH_MSG_MON_MAP: | 1172 | case CEPH_MSG_MON_MAP: |
1033 | case CEPH_MSG_MDS_MAP: | 1173 | case CEPH_MSG_MDS_MAP: |
1034 | case CEPH_MSG_OSD_MAP: | 1174 | case CEPH_MSG_OSD_MAP: |