diff options
Diffstat (limited to 'fs/ceph/mon_client.c')
-rw-r--r-- | fs/ceph/mon_client.c | 149 |
1 files changed, 94 insertions, 55 deletions
diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index 8fdc011ca956..43cfab06fcee 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c | |||
@@ -393,16 +393,64 @@ static void __insert_statfs(struct ceph_mon_client *monc, | |||
393 | rb_insert_color(&new->node, &monc->statfs_request_tree); | 393 | rb_insert_color(&new->node, &monc->statfs_request_tree); |
394 | } | 394 | } |
395 | 395 | ||
396 | static void release_statfs_request(struct kref *kref) | ||
397 | { | ||
398 | struct ceph_mon_statfs_request *req = | ||
399 | container_of(kref, struct ceph_mon_statfs_request, kref); | ||
400 | |||
401 | if (req->reply) | ||
402 | ceph_msg_put(req->reply); | ||
403 | if (req->request) | ||
404 | ceph_msg_put(req->request); | ||
405 | } | ||
406 | |||
407 | static void put_statfs_request(struct ceph_mon_statfs_request *req) | ||
408 | { | ||
409 | kref_put(&req->kref, release_statfs_request); | ||
410 | } | ||
411 | |||
412 | static void get_statfs_request(struct ceph_mon_statfs_request *req) | ||
413 | { | ||
414 | kref_get(&req->kref); | ||
415 | } | ||
416 | |||
417 | static struct ceph_msg *get_statfs_reply(struct ceph_connection *con, | ||
418 | struct ceph_msg_header *hdr, | ||
419 | int *skip) | ||
420 | { | ||
421 | struct ceph_mon_client *monc = con->private; | ||
422 | struct ceph_mon_statfs_request *req; | ||
423 | u64 tid = le64_to_cpu(hdr->tid); | ||
424 | struct ceph_msg *m; | ||
425 | |||
426 | mutex_lock(&monc->mutex); | ||
427 | req = __lookup_statfs(monc, tid); | ||
428 | if (!req) { | ||
429 | dout("get_statfs_reply %lld dne\n", tid); | ||
430 | *skip = 1; | ||
431 | m = NULL; | ||
432 | } else { | ||
433 | dout("get_statfs_reply %lld got %p\n", tid, req->reply); | ||
434 | m = ceph_msg_get(req->reply); | ||
435 | /* | ||
436 | * we don't need to track the connection reading into | ||
437 | * this reply because we only have one open connection | ||
438 | * at a time, ever. | ||
439 | */ | ||
440 | } | ||
441 | mutex_unlock(&monc->mutex); | ||
442 | return m; | ||
443 | } | ||
444 | |||
396 | static void handle_statfs_reply(struct ceph_mon_client *monc, | 445 | static void handle_statfs_reply(struct ceph_mon_client *monc, |
397 | struct ceph_msg *msg) | 446 | struct ceph_msg *msg) |
398 | { | 447 | { |
399 | struct ceph_mon_statfs_request *req; | 448 | struct ceph_mon_statfs_request *req; |
400 | struct ceph_mon_statfs_reply *reply = msg->front.iov_base; | 449 | struct ceph_mon_statfs_reply *reply = msg->front.iov_base; |
401 | u64 tid; | 450 | u64 tid = le64_to_cpu(msg->hdr.tid); |
402 | 451 | ||
403 | if (msg->front.iov_len != sizeof(*reply)) | 452 | if (msg->front.iov_len != sizeof(*reply)) |
404 | goto bad; | 453 | goto bad; |
405 | tid = le64_to_cpu(msg->hdr.tid); | ||
406 | dout("handle_statfs_reply %p tid %llu\n", msg, tid); | 454 | dout("handle_statfs_reply %p tid %llu\n", msg, tid); |
407 | 455 | ||
408 | mutex_lock(&monc->mutex); | 456 | mutex_lock(&monc->mutex); |
@@ -410,10 +458,13 @@ static void handle_statfs_reply(struct ceph_mon_client *monc, | |||
410 | if (req) { | 458 | if (req) { |
411 | *req->buf = reply->st; | 459 | *req->buf = reply->st; |
412 | req->result = 0; | 460 | req->result = 0; |
461 | get_statfs_request(req); | ||
413 | } | 462 | } |
414 | mutex_unlock(&monc->mutex); | 463 | mutex_unlock(&monc->mutex); |
415 | if (req) | 464 | if (req) { |
416 | complete(&req->completion); | 465 | complete(&req->completion); |
466 | put_statfs_request(req); | ||
467 | } | ||
417 | return; | 468 | return; |
418 | 469 | ||
419 | bad: | 470 | bad: |
@@ -422,67 +473,63 @@ bad: | |||
422 | } | 473 | } |
423 | 474 | ||
424 | /* | 475 | /* |
425 | * (re)send a statfs request | 476 | * Do a synchronous statfs(). |
426 | */ | 477 | */ |
427 | static int send_statfs(struct ceph_mon_client *monc, | 478 | int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf) |
428 | struct ceph_mon_statfs_request *req) | ||
429 | { | 479 | { |
430 | struct ceph_msg *msg; | 480 | struct ceph_mon_statfs_request *req; |
431 | struct ceph_mon_statfs *h; | 481 | struct ceph_mon_statfs *h; |
482 | int err; | ||
483 | |||
484 | req = kmalloc(sizeof(*req), GFP_NOFS); | ||
485 | if (!req) | ||
486 | return -ENOMEM; | ||
487 | |||
488 | memset(req, 0, sizeof(*req)); | ||
489 | kref_init(&req->kref); | ||
490 | req->buf = buf; | ||
491 | init_completion(&req->completion); | ||
492 | |||
493 | req->request = ceph_msg_new(CEPH_MSG_STATFS, sizeof(*h), 0, 0, NULL); | ||
494 | if (IS_ERR(req->request)) { | ||
495 | err = PTR_ERR(req->request); | ||
496 | goto out; | ||
497 | } | ||
498 | req->reply = ceph_msg_new(CEPH_MSG_STATFS_REPLY, 1024, 0, 0, NULL); | ||
499 | if (IS_ERR(req->reply)) { | ||
500 | err = PTR_ERR(req->reply); | ||
501 | goto out; | ||
502 | } | ||
432 | 503 | ||
433 | dout("send_statfs tid %llu\n", req->tid); | 504 | /* fill out request */ |
434 | msg = ceph_msg_new(CEPH_MSG_STATFS, sizeof(*h), 0, 0, NULL); | 505 | h = req->request->front.iov_base; |
435 | if (IS_ERR(msg)) | ||
436 | return PTR_ERR(msg); | ||
437 | req->request = msg; | ||
438 | msg->hdr.tid = cpu_to_le64(req->tid); | ||
439 | h = msg->front.iov_base; | ||
440 | h->monhdr.have_version = 0; | 506 | h->monhdr.have_version = 0; |
441 | h->monhdr.session_mon = cpu_to_le16(-1); | 507 | h->monhdr.session_mon = cpu_to_le16(-1); |
442 | h->monhdr.session_mon_tid = 0; | 508 | h->monhdr.session_mon_tid = 0; |
443 | h->fsid = monc->monmap->fsid; | 509 | h->fsid = monc->monmap->fsid; |
444 | ceph_con_send(monc->con, msg); | ||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | /* | ||
449 | * Do a synchronous statfs(). | ||
450 | */ | ||
451 | int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf) | ||
452 | { | ||
453 | struct ceph_mon_statfs_request req; | ||
454 | int err; | ||
455 | |||
456 | req.buf = buf; | ||
457 | init_completion(&req.completion); | ||
458 | |||
459 | /* allocate memory for reply */ | ||
460 | err = ceph_msgpool_resv(&monc->msgpool_statfs_reply, 1); | ||
461 | if (err) | ||
462 | return err; | ||
463 | 510 | ||
464 | /* register request */ | 511 | /* register request */ |
465 | mutex_lock(&monc->mutex); | 512 | mutex_lock(&monc->mutex); |
466 | req.tid = ++monc->last_tid; | 513 | req->tid = ++monc->last_tid; |
467 | req.last_attempt = jiffies; | 514 | req->request->hdr.tid = cpu_to_le64(req->tid); |
468 | req.delay = BASE_DELAY_INTERVAL; | 515 | __insert_statfs(monc, req); |
469 | __insert_statfs(monc, &req); | ||
470 | monc->num_statfs_requests++; | 516 | monc->num_statfs_requests++; |
471 | mutex_unlock(&monc->mutex); | 517 | mutex_unlock(&monc->mutex); |
472 | 518 | ||
473 | /* send request and wait */ | 519 | /* send request and wait */ |
474 | err = send_statfs(monc, &req); | 520 | ceph_con_send(monc->con, ceph_msg_get(req->request)); |
475 | if (!err) | 521 | err = wait_for_completion_interruptible(&req->completion); |
476 | err = wait_for_completion_interruptible(&req.completion); | ||
477 | 522 | ||
478 | mutex_lock(&monc->mutex); | 523 | mutex_lock(&monc->mutex); |
479 | rb_erase(&req.node, &monc->statfs_request_tree); | 524 | rb_erase(&req->node, &monc->statfs_request_tree); |
480 | monc->num_statfs_requests--; | 525 | monc->num_statfs_requests--; |
481 | ceph_msgpool_resv(&monc->msgpool_statfs_reply, -1); | ||
482 | mutex_unlock(&monc->mutex); | 526 | mutex_unlock(&monc->mutex); |
483 | 527 | ||
484 | if (!err) | 528 | if (!err) |
485 | err = req.result; | 529 | err = req->result; |
530 | |||
531 | out: | ||
532 | kref_put(&req->kref, release_statfs_request); | ||
486 | return err; | 533 | return err; |
487 | } | 534 | } |
488 | 535 | ||
@@ -496,7 +543,7 @@ static void __resend_statfs(struct ceph_mon_client *monc) | |||
496 | 543 | ||
497 | for (p = rb_first(&monc->statfs_request_tree); p; p = rb_next(p)) { | 544 | for (p = rb_first(&monc->statfs_request_tree); p; p = rb_next(p)) { |
498 | req = rb_entry(p, struct ceph_mon_statfs_request, node); | 545 | req = rb_entry(p, struct ceph_mon_statfs_request, node); |
499 | send_statfs(monc, req); | 546 | ceph_con_send(monc->con, ceph_msg_get(req->request)); |
500 | } | 547 | } |
501 | } | 548 | } |
502 | 549 | ||
@@ -591,13 +638,9 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl) | |||
591 | sizeof(struct ceph_mon_subscribe_ack), 1, false); | 638 | sizeof(struct ceph_mon_subscribe_ack), 1, false); |
592 | if (err < 0) | 639 | if (err < 0) |
593 | goto out_monmap; | 640 | goto out_monmap; |
594 | err = ceph_msgpool_init(&monc->msgpool_statfs_reply, | ||
595 | sizeof(struct ceph_mon_statfs_reply), 0, false); | ||
596 | if (err < 0) | ||
597 | goto out_pool1; | ||
598 | err = ceph_msgpool_init(&monc->msgpool_auth_reply, 4096, 1, false); | 641 | err = ceph_msgpool_init(&monc->msgpool_auth_reply, 4096, 1, false); |
599 | if (err < 0) | 642 | if (err < 0) |
600 | goto out_pool2; | 643 | goto out_pool; |
601 | 644 | ||
602 | monc->m_auth = ceph_msg_new(CEPH_MSG_AUTH, 4096, 0, 0, NULL); | 645 | monc->m_auth = ceph_msg_new(CEPH_MSG_AUTH, 4096, 0, 0, NULL); |
603 | monc->pending_auth = 0; | 646 | monc->pending_auth = 0; |
@@ -624,10 +667,8 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl) | |||
624 | 667 | ||
625 | out_pool3: | 668 | out_pool3: |
626 | ceph_msgpool_destroy(&monc->msgpool_auth_reply); | 669 | ceph_msgpool_destroy(&monc->msgpool_auth_reply); |
627 | out_pool2: | 670 | out_pool: |
628 | ceph_msgpool_destroy(&monc->msgpool_subscribe_ack); | 671 | ceph_msgpool_destroy(&monc->msgpool_subscribe_ack); |
629 | out_pool1: | ||
630 | ceph_msgpool_destroy(&monc->msgpool_statfs_reply); | ||
631 | out_monmap: | 672 | out_monmap: |
632 | kfree(monc->monmap); | 673 | kfree(monc->monmap); |
633 | out: | 674 | out: |
@@ -652,7 +693,6 @@ void ceph_monc_stop(struct ceph_mon_client *monc) | |||
652 | 693 | ||
653 | ceph_msg_put(monc->m_auth); | 694 | ceph_msg_put(monc->m_auth); |
654 | ceph_msgpool_destroy(&monc->msgpool_subscribe_ack); | 695 | ceph_msgpool_destroy(&monc->msgpool_subscribe_ack); |
655 | ceph_msgpool_destroy(&monc->msgpool_statfs_reply); | ||
656 | ceph_msgpool_destroy(&monc->msgpool_auth_reply); | 696 | ceph_msgpool_destroy(&monc->msgpool_auth_reply); |
657 | 697 | ||
658 | kfree(monc->monmap); | 698 | kfree(monc->monmap); |
@@ -773,8 +813,7 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con, | |||
773 | m = ceph_msgpool_get(&monc->msgpool_subscribe_ack, front_len); | 813 | m = ceph_msgpool_get(&monc->msgpool_subscribe_ack, front_len); |
774 | break; | 814 | break; |
775 | case CEPH_MSG_STATFS_REPLY: | 815 | case CEPH_MSG_STATFS_REPLY: |
776 | m = ceph_msgpool_get(&monc->msgpool_statfs_reply, front_len); | 816 | return get_statfs_reply(con, hdr, skip); |
777 | break; | ||
778 | case CEPH_MSG_AUTH_REPLY: | 817 | case CEPH_MSG_AUTH_REPLY: |
779 | m = ceph_msgpool_get(&monc->msgpool_auth_reply, front_len); | 818 | m = ceph_msgpool_get(&monc->msgpool_auth_reply, front_len); |
780 | break; | 819 | break; |