diff options
Diffstat (limited to 'net/ceph')
| -rw-r--r-- | net/ceph/ceph_common.c | 2 | ||||
| -rw-r--r-- | net/ceph/debugfs.c | 2 | ||||
| -rw-r--r-- | net/ceph/mon_client.c | 123 |
3 files changed, 122 insertions, 5 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 8903dcee8d8e..d1a62c69a9f4 100644 --- a/net/ceph/debugfs.c +++ b/net/ceph/debugfs.c | |||
| @@ -129,6 +129,8 @@ static int monc_show(struct seq_file *s, void *p) | |||
| 129 | seq_printf(s, "%llu statfs\n", req->tid); | 129 | seq_printf(s, "%llu statfs\n", req->tid); |
| 130 | else if (op == CEPH_MSG_POOLOP) | 130 | else if (op == CEPH_MSG_POOLOP) |
| 131 | seq_printf(s, "%llu poolop\n", req->tid); | 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); | ||
| 132 | else | 134 | else |
| 133 | seq_printf(s, "%llu unknown\n", req->tid); | 135 | seq_printf(s, "%llu unknown\n", req->tid); |
| 134 | } | 136 | } |
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c index 2ac9ef35110b..11d8d2f2708a 100644 --- a/net/ceph/mon_client.c +++ b/net/ceph/mon_client.c | |||
| @@ -477,14 +477,13 @@ static struct ceph_msg *get_generic_reply(struct ceph_connection *con, | |||
| 477 | return m; | 477 | return m; |
| 478 | } | 478 | } |
| 479 | 479 | ||
| 480 | static int do_generic_request(struct ceph_mon_client *monc, | 480 | static int __do_generic_request(struct ceph_mon_client *monc, u64 tid, |
| 481 | struct ceph_mon_generic_request *req) | 481 | struct ceph_mon_generic_request *req) |
| 482 | { | 482 | { |
| 483 | int err; | 483 | int err; |
| 484 | 484 | ||
| 485 | /* register request */ | 485 | /* register request */ |
| 486 | mutex_lock(&monc->mutex); | 486 | req->tid = tid != 0 ? tid : ++monc->last_tid; |
| 487 | req->tid = ++monc->last_tid; | ||
| 488 | req->request->hdr.tid = cpu_to_le64(req->tid); | 487 | req->request->hdr.tid = cpu_to_le64(req->tid); |
| 489 | __insert_generic_request(monc, req); | 488 | __insert_generic_request(monc, req); |
| 490 | monc->num_generic_requests++; | 489 | monc->num_generic_requests++; |
| @@ -496,13 +495,24 @@ static int do_generic_request(struct ceph_mon_client *monc, | |||
| 496 | mutex_lock(&monc->mutex); | 495 | mutex_lock(&monc->mutex); |
| 497 | rb_erase(&req->node, &monc->generic_request_tree); | 496 | rb_erase(&req->node, &monc->generic_request_tree); |
| 498 | monc->num_generic_requests--; | 497 | monc->num_generic_requests--; |
| 499 | mutex_unlock(&monc->mutex); | ||
| 500 | 498 | ||
| 501 | if (!err) | 499 | if (!err) |
| 502 | err = req->result; | 500 | err = req->result; |
| 503 | return err; | 501 | return err; |
| 504 | } | 502 | } |
| 505 | 503 | ||
| 504 | static int do_generic_request(struct ceph_mon_client *monc, | ||
| 505 | struct ceph_mon_generic_request *req) | ||
| 506 | { | ||
| 507 | int err; | ||
| 508 | |||
| 509 | mutex_lock(&monc->mutex); | ||
| 510 | err = __do_generic_request(monc, 0, req); | ||
| 511 | mutex_unlock(&monc->mutex); | ||
| 512 | |||
| 513 | return err; | ||
| 514 | } | ||
| 515 | |||
| 506 | /* | 516 | /* |
| 507 | * statfs | 517 | * statfs |
| 508 | */ | 518 | */ |
| @@ -579,6 +589,96 @@ out: | |||
| 579 | } | 589 | } |
| 580 | EXPORT_SYMBOL(ceph_monc_do_statfs); | 590 | EXPORT_SYMBOL(ceph_monc_do_statfs); |
| 581 | 591 | ||
| 592 | static void handle_get_version_reply(struct ceph_mon_client *monc, | ||
| 593 | struct ceph_msg *msg) | ||
| 594 | { | ||
| 595 | struct ceph_mon_generic_request *req; | ||
| 596 | u64 tid = le64_to_cpu(msg->hdr.tid); | ||
| 597 | void *p = msg->front.iov_base; | ||
| 598 | void *end = p + msg->front_alloc_len; | ||
| 599 | u64 handle; | ||
| 600 | |||
| 601 | dout("%s %p tid %llu\n", __func__, msg, tid); | ||
| 602 | |||
| 603 | ceph_decode_need(&p, end, 2*sizeof(u64), bad); | ||
| 604 | handle = ceph_decode_64(&p); | ||
| 605 | if (tid != 0 && tid != handle) | ||
| 606 | goto bad; | ||
| 607 | |||
| 608 | mutex_lock(&monc->mutex); | ||
| 609 | req = __lookup_generic_req(monc, handle); | ||
| 610 | if (req) { | ||
| 611 | *(u64 *)req->buf = ceph_decode_64(&p); | ||
| 612 | req->result = 0; | ||
| 613 | get_generic_request(req); | ||
| 614 | } | ||
| 615 | mutex_unlock(&monc->mutex); | ||
| 616 | if (req) { | ||
| 617 | complete_all(&req->completion); | ||
| 618 | put_generic_request(req); | ||
| 619 | } | ||
| 620 | |||
| 621 | return; | ||
| 622 | bad: | ||
| 623 | pr_err("corrupt mon_get_version reply\n"); | ||
| 624 | ceph_msg_dump(msg); | ||
| 625 | } | ||
| 626 | |||
| 627 | /* | ||
| 628 | * Send MMonGetVersion and wait for the reply. | ||
| 629 | * | ||
| 630 | * @what: one of "mdsmap", "osdmap" or "monmap" | ||
| 631 | */ | ||
| 632 | int ceph_monc_do_get_version(struct ceph_mon_client *monc, const char *what, | ||
| 633 | u64 *newest) | ||
| 634 | { | ||
| 635 | struct ceph_mon_generic_request *req; | ||
| 636 | void *p, *end; | ||
| 637 | u64 tid; | ||
| 638 | int err; | ||
| 639 | |||
| 640 | req = kzalloc(sizeof(*req), GFP_NOFS); | ||
| 641 | if (!req) | ||
| 642 | return -ENOMEM; | ||
| 643 | |||
| 644 | kref_init(&req->kref); | ||
| 645 | req->buf = newest; | ||
| 646 | req->buf_len = sizeof(*newest); | ||
| 647 | init_completion(&req->completion); | ||
| 648 | |||
| 649 | req->request = ceph_msg_new(CEPH_MSG_MON_GET_VERSION, | ||
| 650 | sizeof(u64) + sizeof(u32) + strlen(what), | ||
| 651 | GFP_NOFS, true); | ||
| 652 | if (!req->request) { | ||
| 653 | err = -ENOMEM; | ||
| 654 | goto out; | ||
| 655 | } | ||
| 656 | |||
| 657 | req->reply = ceph_msg_new(CEPH_MSG_MON_GET_VERSION_REPLY, 1024, | ||
| 658 | GFP_NOFS, true); | ||
| 659 | if (!req->reply) { | ||
| 660 | err = -ENOMEM; | ||
| 661 | goto out; | ||
| 662 | } | ||
| 663 | |||
| 664 | p = req->request->front.iov_base; | ||
| 665 | end = p + req->request->front_alloc_len; | ||
| 666 | |||
| 667 | /* fill out request */ | ||
| 668 | mutex_lock(&monc->mutex); | ||
| 669 | tid = ++monc->last_tid; | ||
| 670 | ceph_encode_64(&p, tid); /* handle */ | ||
| 671 | ceph_encode_string(&p, end, what, strlen(what)); | ||
| 672 | |||
| 673 | err = __do_generic_request(monc, tid, req); | ||
| 674 | |||
| 675 | mutex_unlock(&monc->mutex); | ||
| 676 | out: | ||
| 677 | kref_put(&req->kref, release_generic_request); | ||
| 678 | return err; | ||
| 679 | } | ||
| 680 | EXPORT_SYMBOL(ceph_monc_do_get_version); | ||
| 681 | |||
| 582 | /* | 682 | /* |
| 583 | * pool ops | 683 | * pool ops |
| 584 | */ | 684 | */ |
| @@ -981,6 +1081,10 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) | |||
| 981 | handle_statfs_reply(monc, msg); | 1081 | handle_statfs_reply(monc, msg); |
| 982 | break; | 1082 | break; |
| 983 | 1083 | ||
| 1084 | case CEPH_MSG_MON_GET_VERSION_REPLY: | ||
| 1085 | handle_get_version_reply(monc, msg); | ||
| 1086 | break; | ||
| 1087 | |||
| 984 | case CEPH_MSG_POOLOP_REPLY: | 1088 | case CEPH_MSG_POOLOP_REPLY: |
| 985 | handle_poolop_reply(monc, msg); | 1089 | handle_poolop_reply(monc, msg); |
| 986 | break; | 1090 | break; |
| @@ -1029,6 +1133,15 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con, | |||
| 1029 | case CEPH_MSG_AUTH_REPLY: | 1133 | case CEPH_MSG_AUTH_REPLY: |
| 1030 | m = ceph_msg_get(monc->m_auth_reply); | 1134 | m = ceph_msg_get(monc->m_auth_reply); |
| 1031 | break; | 1135 | break; |
| 1136 | case CEPH_MSG_MON_GET_VERSION_REPLY: | ||
| 1137 | if (le64_to_cpu(hdr->tid) != 0) | ||
| 1138 | return get_generic_reply(con, hdr, skip); | ||
| 1139 | |||
| 1140 | /* | ||
| 1141 | * Older OSDs don't set reply tid even if the orignal | ||
| 1142 | * request had a non-zero tid. Workaround this weirdness | ||
| 1143 | * by falling through to the allocate case. | ||
| 1144 | */ | ||
| 1032 | case CEPH_MSG_MON_MAP: | 1145 | case CEPH_MSG_MON_MAP: |
| 1033 | case CEPH_MSG_MDS_MAP: | 1146 | case CEPH_MSG_MDS_MAP: |
| 1034 | case CEPH_MSG_OSD_MAP: | 1147 | case CEPH_MSG_OSD_MAP: |
