aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ceph/ceph_common.c2
-rw-r--r--net/ceph/debugfs.c8
-rw-r--r--net/ceph/mon_client.c150
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}
299EXPORT_SYMBOL(ceph_monc_request_next_osdmap);
300
301int 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}
325EXPORT_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
480static int do_generic_request(struct ceph_mon_client *monc, 507static 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
531static 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}
580EXPORT_SYMBOL(ceph_monc_do_statfs); 617EXPORT_SYMBOL(ceph_monc_do_statfs);
581 618
619static 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;
649bad:
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 */
659int 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);
703out:
704 kref_put(&req->kref, release_generic_request);
705 return err;
706}
707EXPORT_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: