diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-13 02:06:23 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-13 02:06:23 -0400 |
| commit | 6d87c225f5d82d29243dc124f1ffcbb0e14ec358 (patch) | |
| tree | 7d72e2e6a77ec0911e86911d2ddae62c1b4161cf /net | |
| parent | 338c09a94b14c449dd53227e9bea44816668c6a5 (diff) | |
| parent | 22001f619f29ddf66582d834223dcff4c0b74595 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client
Pull Ceph updates from Sage Weil:
"This has a mix of bug fixes and cleanups.
Alex's patch fixes a rare race in RBD. Ilya's patches fix an ENOENT
check when a second rbd image is mapped and a couple memory leaks.
Zheng fixes several issues with fragmented directories and multiple
MDSs. Josh fixes a spin/sleep issue, and Josh and Guangliang's
patches fix setting and unsetting RBD images read-only.
Naturally there are several other cleanups mixed in for good measure"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client: (23 commits)
rbd: only set disk to read-only once
rbd: move calls that may sleep out of spin lock range
rbd: add ioctl for rbd
ceph: use truncate_pagecache() instead of truncate_inode_pages()
ceph: include time stamp in every MDS request
rbd: fix ida/idr memory leak
rbd: use reference counts for image requests
rbd: fix osd_request memory leak in __rbd_dev_header_watch_sync()
rbd: make sure we have latest osdmap on 'rbd map'
libceph: add ceph_monc_wait_osdmap()
libceph: mon_get_version request infrastructure
libceph: recognize poolop requests in debugfs
ceph: refactor readpage_nounlock() to make the logic clearer
mds: check cap ID when handling cap export message
ceph: remember subtree root dirfrag's auth MDS
ceph: introduce ceph_fill_fragtree()
ceph: handle cap import atomically
ceph: pre-allocate ceph_cap struct for ceph_add_cap()
ceph: update inode fields according to issued caps
rbd: replace IS_ERR and PTR_ERR with PTR_ERR_OR_ZERO
...
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: |
