diff options
author | Yehuda Sadeh <yehuda@hq.newdream.net> | 2010-05-17 15:40:28 -0400 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-08-10 17:41:25 -0400 |
commit | e56fa10e92e077d456cbc33b7025032887772b33 (patch) | |
tree | ada8fefc9fdbe457a6f387b05e984478065a698b /fs/ceph/mon_client.c | |
parent | 0eb6cd49f6e3ec523787d09cf08d3179be270db4 (diff) |
ceph: generalize mon requests, add pool op support
Generalize the current statfs synchronous requests, and support pool_ops.
Signed-off-by: Yehuda Sadeh <yehuda@hq.newdream.net>
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/mon_client.c')
-rw-r--r-- | fs/ceph/mon_client.c | 170 |
1 files changed, 153 insertions, 17 deletions
diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index 54fe01c50706..b2a5a3e4a671 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c | |||
@@ -349,7 +349,7 @@ out: | |||
349 | } | 349 | } |
350 | 350 | ||
351 | /* | 351 | /* |
352 | * statfs | 352 | * generic requests (e.g., statfs, poolop) |
353 | */ | 353 | */ |
354 | static struct ceph_mon_generic_request *__lookup_generic_req( | 354 | static struct ceph_mon_generic_request *__lookup_generic_req( |
355 | struct ceph_mon_client *monc, u64 tid) | 355 | struct ceph_mon_client *monc, u64 tid) |
@@ -442,6 +442,35 @@ static struct ceph_msg *get_generic_reply(struct ceph_connection *con, | |||
442 | return m; | 442 | return m; |
443 | } | 443 | } |
444 | 444 | ||
445 | static int do_generic_request(struct ceph_mon_client *monc, | ||
446 | struct ceph_mon_generic_request *req) | ||
447 | { | ||
448 | int err; | ||
449 | |||
450 | /* register request */ | ||
451 | mutex_lock(&monc->mutex); | ||
452 | req->tid = ++monc->last_tid; | ||
453 | req->request->hdr.tid = cpu_to_le64(req->tid); | ||
454 | __insert_generic_request(monc, req); | ||
455 | monc->num_generic_requests++; | ||
456 | ceph_con_send(monc->con, ceph_msg_get(req->request)); | ||
457 | mutex_unlock(&monc->mutex); | ||
458 | |||
459 | err = wait_for_completion_interruptible(&req->completion); | ||
460 | |||
461 | mutex_lock(&monc->mutex); | ||
462 | rb_erase(&req->node, &monc->generic_request_tree); | ||
463 | monc->num_generic_requests--; | ||
464 | mutex_unlock(&monc->mutex); | ||
465 | |||
466 | if (!err) | ||
467 | err = req->result; | ||
468 | return err; | ||
469 | } | ||
470 | |||
471 | /* | ||
472 | * statfs | ||
473 | */ | ||
445 | static void handle_statfs_reply(struct ceph_mon_client *monc, | 474 | static void handle_statfs_reply(struct ceph_mon_client *monc, |
446 | struct ceph_msg *msg) | 475 | struct ceph_msg *msg) |
447 | { | 476 | { |
@@ -468,7 +497,7 @@ static void handle_statfs_reply(struct ceph_mon_client *monc, | |||
468 | return; | 497 | return; |
469 | 498 | ||
470 | bad: | 499 | bad: |
471 | pr_err("corrupt generic reply, no tid\n"); | 500 | pr_err("corrupt generic reply, tid %llu\n", tid); |
472 | ceph_msg_dump(msg); | 501 | ceph_msg_dump(msg); |
473 | } | 502 | } |
474 | 503 | ||
@@ -487,6 +516,7 @@ int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf) | |||
487 | 516 | ||
488 | kref_init(&req->kref); | 517 | kref_init(&req->kref); |
489 | req->buf = buf; | 518 | req->buf = buf; |
519 | req->buf_len = sizeof(*buf); | ||
490 | init_completion(&req->completion); | 520 | init_completion(&req->completion); |
491 | 521 | ||
492 | err = -ENOMEM; | 522 | err = -ENOMEM; |
@@ -504,33 +534,134 @@ int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf) | |||
504 | h->monhdr.session_mon_tid = 0; | 534 | h->monhdr.session_mon_tid = 0; |
505 | h->fsid = monc->monmap->fsid; | 535 | h->fsid = monc->monmap->fsid; |
506 | 536 | ||
507 | /* register request */ | 537 | err = do_generic_request(monc, req); |
508 | mutex_lock(&monc->mutex); | ||
509 | req->tid = ++monc->last_tid; | ||
510 | req->request->hdr.tid = cpu_to_le64(req->tid); | ||
511 | __insert_generic_request(monc, req); | ||
512 | monc->num_generic_requests++; | ||
513 | mutex_unlock(&monc->mutex); | ||
514 | 538 | ||
515 | /* send request and wait */ | 539 | out: |
516 | ceph_con_send(monc->con, ceph_msg_get(req->request)); | 540 | kref_put(&req->kref, release_generic_request); |
517 | err = wait_for_completion_interruptible(&req->completion); | 541 | return err; |
542 | } | ||
543 | |||
544 | /* | ||
545 | * pool ops | ||
546 | */ | ||
547 | static int get_poolop_reply_buf(const char *src, size_t src_len, | ||
548 | char *dst, size_t dst_len) | ||
549 | { | ||
550 | u32 buf_len; | ||
551 | |||
552 | if (src_len != sizeof(u32) + dst_len) | ||
553 | return -EINVAL; | ||
554 | |||
555 | buf_len = le32_to_cpu(*(u32 *)src); | ||
556 | if (buf_len != dst_len) | ||
557 | return -EINVAL; | ||
558 | |||
559 | memcpy(dst, src + sizeof(u32), dst_len); | ||
560 | return 0; | ||
561 | } | ||
562 | |||
563 | static void handle_poolop_reply(struct ceph_mon_client *monc, | ||
564 | struct ceph_msg *msg) | ||
565 | { | ||
566 | struct ceph_mon_generic_request *req; | ||
567 | struct ceph_mon_poolop_reply *reply = msg->front.iov_base; | ||
568 | u64 tid = le64_to_cpu(msg->hdr.tid); | ||
569 | |||
570 | if (msg->front.iov_len < sizeof(*reply)) | ||
571 | goto bad; | ||
572 | dout("handle_poolop_reply %p tid %llu\n", msg, tid); | ||
518 | 573 | ||
519 | mutex_lock(&monc->mutex); | 574 | mutex_lock(&monc->mutex); |
520 | rb_erase(&req->node, &monc->generic_request_tree); | 575 | req = __lookup_generic_req(monc, tid); |
521 | monc->num_generic_requests--; | 576 | if (req) { |
577 | if (req->buf_len && | ||
578 | get_poolop_reply_buf(msg->front.iov_base + sizeof(*reply), | ||
579 | msg->front.iov_len - sizeof(*reply), | ||
580 | req->buf, req->buf_len) < 0) { | ||
581 | mutex_unlock(&monc->mutex); | ||
582 | goto bad; | ||
583 | } | ||
584 | req->result = le32_to_cpu(reply->reply_code); | ||
585 | get_generic_request(req); | ||
586 | } | ||
522 | mutex_unlock(&monc->mutex); | 587 | mutex_unlock(&monc->mutex); |
588 | if (req) { | ||
589 | complete(&req->completion); | ||
590 | put_generic_request(req); | ||
591 | } | ||
592 | return; | ||
523 | 593 | ||
524 | if (!err) | 594 | bad: |
525 | err = req->result; | 595 | pr_err("corrupt generic reply, tid %llu\n", tid); |
596 | ceph_msg_dump(msg); | ||
597 | } | ||
598 | |||
599 | /* | ||
600 | * Do a synchronous pool op. | ||
601 | */ | ||
602 | int ceph_monc_do_poolop(struct ceph_mon_client *monc, u32 op, | ||
603 | u32 pool, u64 snapid, | ||
604 | char *buf, int len) | ||
605 | { | ||
606 | struct ceph_mon_generic_request *req; | ||
607 | struct ceph_mon_poolop *h; | ||
608 | int err; | ||
609 | |||
610 | req = kzalloc(sizeof(*req), GFP_NOFS); | ||
611 | if (!req) | ||
612 | return -ENOMEM; | ||
613 | |||
614 | kref_init(&req->kref); | ||
615 | req->buf = buf; | ||
616 | req->buf_len = len; | ||
617 | init_completion(&req->completion); | ||
618 | |||
619 | err = -ENOMEM; | ||
620 | req->request = ceph_msg_new(CEPH_MSG_POOLOP, sizeof(*h), GFP_NOFS); | ||
621 | if (!req->request) | ||
622 | goto out; | ||
623 | req->reply = ceph_msg_new(CEPH_MSG_POOLOP_REPLY, 1024, GFP_NOFS); | ||
624 | if (!req->reply) | ||
625 | goto out; | ||
626 | |||
627 | /* fill out request */ | ||
628 | req->request->hdr.version = cpu_to_le16(2); | ||
629 | h = req->request->front.iov_base; | ||
630 | h->monhdr.have_version = 0; | ||
631 | h->monhdr.session_mon = cpu_to_le16(-1); | ||
632 | h->monhdr.session_mon_tid = 0; | ||
633 | h->fsid = monc->monmap->fsid; | ||
634 | h->pool = cpu_to_le32(pool); | ||
635 | h->op = cpu_to_le32(op); | ||
636 | h->auid = 0; | ||
637 | h->snapid = cpu_to_le64(snapid); | ||
638 | h->name_len = 0; | ||
639 | |||
640 | err = do_generic_request(monc, req); | ||
526 | 641 | ||
527 | out: | 642 | out: |
528 | kref_put(&req->kref, release_generic_request); | 643 | kref_put(&req->kref, release_generic_request); |
529 | return err; | 644 | return err; |
530 | } | 645 | } |
531 | 646 | ||
647 | int ceph_monc_create_snapid(struct ceph_mon_client *monc, | ||
648 | u32 pool, u64 *snapid) | ||
649 | { | ||
650 | return ceph_monc_do_poolop(monc, POOL_OP_CREATE_UNMANAGED_SNAP, | ||
651 | pool, 0, (char *)snapid, sizeof(*snapid)); | ||
652 | |||
653 | } | ||
654 | |||
655 | int ceph_monc_delete_snapid(struct ceph_mon_client *monc, | ||
656 | u32 pool, u64 snapid) | ||
657 | { | ||
658 | return ceph_monc_do_poolop(monc, POOL_OP_CREATE_UNMANAGED_SNAP, | ||
659 | pool, snapid, 0, 0); | ||
660 | |||
661 | } | ||
662 | |||
532 | /* | 663 | /* |
533 | * Resend pending statfs requests. | 664 | * Resend pending generic requests. |
534 | */ | 665 | */ |
535 | static void __resend_generic_request(struct ceph_mon_client *monc) | 666 | static void __resend_generic_request(struct ceph_mon_client *monc) |
536 | { | 667 | { |
@@ -783,6 +914,10 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) | |||
783 | handle_statfs_reply(monc, msg); | 914 | handle_statfs_reply(monc, msg); |
784 | break; | 915 | break; |
785 | 916 | ||
917 | case CEPH_MSG_POOLOP_REPLY: | ||
918 | handle_poolop_reply(monc, msg); | ||
919 | break; | ||
920 | |||
786 | case CEPH_MSG_MON_MAP: | 921 | case CEPH_MSG_MON_MAP: |
787 | ceph_monc_handle_map(monc, msg); | 922 | ceph_monc_handle_map(monc, msg); |
788 | break; | 923 | break; |
@@ -820,6 +955,7 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con, | |||
820 | case CEPH_MSG_MON_SUBSCRIBE_ACK: | 955 | case CEPH_MSG_MON_SUBSCRIBE_ACK: |
821 | m = ceph_msg_get(monc->m_subscribe_ack); | 956 | m = ceph_msg_get(monc->m_subscribe_ack); |
822 | break; | 957 | break; |
958 | case CEPH_MSG_POOLOP_REPLY: | ||
823 | case CEPH_MSG_STATFS_REPLY: | 959 | case CEPH_MSG_STATFS_REPLY: |
824 | return get_generic_reply(con, hdr, skip); | 960 | return get_generic_reply(con, hdr, skip); |
825 | case CEPH_MSG_AUTH_REPLY: | 961 | case CEPH_MSG_AUTH_REPLY: |