diff options
Diffstat (limited to 'fs/ceph/mds_client.c')
-rw-r--r-- | fs/ceph/mds_client.c | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index a2600101ec22..5c7920be6420 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -328,6 +328,8 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, | |||
328 | struct ceph_mds_session *s; | 328 | struct ceph_mds_session *s; |
329 | 329 | ||
330 | s = kzalloc(sizeof(*s), GFP_NOFS); | 330 | s = kzalloc(sizeof(*s), GFP_NOFS); |
331 | if (!s) | ||
332 | return ERR_PTR(-ENOMEM); | ||
331 | s->s_mdsc = mdsc; | 333 | s->s_mdsc = mdsc; |
332 | s->s_mds = mds; | 334 | s->s_mds = mds; |
333 | s->s_state = CEPH_MDS_SESSION_NEW; | 335 | s->s_state = CEPH_MDS_SESSION_NEW; |
@@ -529,7 +531,7 @@ static void __unregister_request(struct ceph_mds_client *mdsc, | |||
529 | { | 531 | { |
530 | dout("__unregister_request %p tid %lld\n", req, req->r_tid); | 532 | dout("__unregister_request %p tid %lld\n", req, req->r_tid); |
531 | rb_erase(&req->r_node, &mdsc->request_tree); | 533 | rb_erase(&req->r_node, &mdsc->request_tree); |
532 | ceph_mdsc_put_request(req); | 534 | RB_CLEAR_NODE(&req->r_node); |
533 | 535 | ||
534 | if (req->r_unsafe_dir) { | 536 | if (req->r_unsafe_dir) { |
535 | struct ceph_inode_info *ci = ceph_inode(req->r_unsafe_dir); | 537 | struct ceph_inode_info *ci = ceph_inode(req->r_unsafe_dir); |
@@ -538,6 +540,8 @@ static void __unregister_request(struct ceph_mds_client *mdsc, | |||
538 | list_del_init(&req->r_unsafe_dir_item); | 540 | list_del_init(&req->r_unsafe_dir_item); |
539 | spin_unlock(&ci->i_unsafe_lock); | 541 | spin_unlock(&ci->i_unsafe_lock); |
540 | } | 542 | } |
543 | |||
544 | ceph_mdsc_put_request(req); | ||
541 | } | 545 | } |
542 | 546 | ||
543 | /* | 547 | /* |
@@ -862,6 +866,7 @@ static int send_renew_caps(struct ceph_mds_client *mdsc, | |||
862 | if (time_after_eq(jiffies, session->s_cap_ttl) && | 866 | if (time_after_eq(jiffies, session->s_cap_ttl) && |
863 | time_after_eq(session->s_cap_ttl, session->s_renew_requested)) | 867 | time_after_eq(session->s_cap_ttl, session->s_renew_requested)) |
864 | pr_info("mds%d caps stale\n", session->s_mds); | 868 | pr_info("mds%d caps stale\n", session->s_mds); |
869 | session->s_renew_requested = jiffies; | ||
865 | 870 | ||
866 | /* do not try to renew caps until a recovering mds has reconnected | 871 | /* do not try to renew caps until a recovering mds has reconnected |
867 | * with its clients. */ | 872 | * with its clients. */ |
@@ -874,7 +879,6 @@ static int send_renew_caps(struct ceph_mds_client *mdsc, | |||
874 | 879 | ||
875 | dout("send_renew_caps to mds%d (%s)\n", session->s_mds, | 880 | dout("send_renew_caps to mds%d (%s)\n", session->s_mds, |
876 | ceph_mds_state_name(state)); | 881 | ceph_mds_state_name(state)); |
877 | session->s_renew_requested = jiffies; | ||
878 | msg = create_session_msg(CEPH_SESSION_REQUEST_RENEWCAPS, | 882 | msg = create_session_msg(CEPH_SESSION_REQUEST_RENEWCAPS, |
879 | ++session->s_renew_seq); | 883 | ++session->s_renew_seq); |
880 | if (IS_ERR(msg)) | 884 | if (IS_ERR(msg)) |
@@ -1566,8 +1570,13 @@ static int __do_request(struct ceph_mds_client *mdsc, | |||
1566 | 1570 | ||
1567 | /* get, open session */ | 1571 | /* get, open session */ |
1568 | session = __ceph_lookup_mds_session(mdsc, mds); | 1572 | session = __ceph_lookup_mds_session(mdsc, mds); |
1569 | if (!session) | 1573 | if (!session) { |
1570 | session = register_session(mdsc, mds); | 1574 | session = register_session(mdsc, mds); |
1575 | if (IS_ERR(session)) { | ||
1576 | err = PTR_ERR(session); | ||
1577 | goto finish; | ||
1578 | } | ||
1579 | } | ||
1571 | dout("do_request mds%d session %p state %s\n", mds, session, | 1580 | dout("do_request mds%d session %p state %s\n", mds, session, |
1572 | session_state_name(session->s_state)); | 1581 | session_state_name(session->s_state)); |
1573 | if (session->s_state != CEPH_MDS_SESSION_OPEN && | 1582 | if (session->s_state != CEPH_MDS_SESSION_OPEN && |
@@ -1770,7 +1779,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) | |||
1770 | dout("handle_reply %p\n", req); | 1779 | dout("handle_reply %p\n", req); |
1771 | 1780 | ||
1772 | /* correct session? */ | 1781 | /* correct session? */ |
1773 | if (!req->r_session && req->r_session != session) { | 1782 | if (req->r_session != session) { |
1774 | pr_err("mdsc_handle_reply got %llu on session mds%d" | 1783 | pr_err("mdsc_handle_reply got %llu on session mds%d" |
1775 | " not mds%d\n", tid, session->s_mds, | 1784 | " not mds%d\n", tid, session->s_mds, |
1776 | req->r_session ? req->r_session->s_mds : -1); | 1785 | req->r_session ? req->r_session->s_mds : -1); |
@@ -2682,29 +2691,41 @@ void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc) | |||
2682 | */ | 2691 | */ |
2683 | static void wait_unsafe_requests(struct ceph_mds_client *mdsc, u64 want_tid) | 2692 | static void wait_unsafe_requests(struct ceph_mds_client *mdsc, u64 want_tid) |
2684 | { | 2693 | { |
2685 | struct ceph_mds_request *req = NULL; | 2694 | struct ceph_mds_request *req = NULL, *nextreq; |
2686 | struct rb_node *n; | 2695 | struct rb_node *n; |
2687 | 2696 | ||
2688 | mutex_lock(&mdsc->mutex); | 2697 | mutex_lock(&mdsc->mutex); |
2689 | dout("wait_unsafe_requests want %lld\n", want_tid); | 2698 | dout("wait_unsafe_requests want %lld\n", want_tid); |
2699 | restart: | ||
2690 | req = __get_oldest_req(mdsc); | 2700 | req = __get_oldest_req(mdsc); |
2691 | while (req && req->r_tid <= want_tid) { | 2701 | while (req && req->r_tid <= want_tid) { |
2702 | /* find next request */ | ||
2703 | n = rb_next(&req->r_node); | ||
2704 | if (n) | ||
2705 | nextreq = rb_entry(n, struct ceph_mds_request, r_node); | ||
2706 | else | ||
2707 | nextreq = NULL; | ||
2692 | if ((req->r_op & CEPH_MDS_OP_WRITE)) { | 2708 | if ((req->r_op & CEPH_MDS_OP_WRITE)) { |
2693 | /* write op */ | 2709 | /* write op */ |
2694 | ceph_mdsc_get_request(req); | 2710 | ceph_mdsc_get_request(req); |
2711 | if (nextreq) | ||
2712 | ceph_mdsc_get_request(nextreq); | ||
2695 | mutex_unlock(&mdsc->mutex); | 2713 | mutex_unlock(&mdsc->mutex); |
2696 | dout("wait_unsafe_requests wait on %llu (want %llu)\n", | 2714 | dout("wait_unsafe_requests wait on %llu (want %llu)\n", |
2697 | req->r_tid, want_tid); | 2715 | req->r_tid, want_tid); |
2698 | wait_for_completion(&req->r_safe_completion); | 2716 | wait_for_completion(&req->r_safe_completion); |
2699 | mutex_lock(&mdsc->mutex); | 2717 | mutex_lock(&mdsc->mutex); |
2700 | n = rb_next(&req->r_node); | ||
2701 | ceph_mdsc_put_request(req); | 2718 | ceph_mdsc_put_request(req); |
2702 | } else { | 2719 | if (!nextreq) |
2703 | n = rb_next(&req->r_node); | 2720 | break; /* next dne before, so we're done! */ |
2721 | if (RB_EMPTY_NODE(&nextreq->r_node)) { | ||
2722 | /* next request was removed from tree */ | ||
2723 | ceph_mdsc_put_request(nextreq); | ||
2724 | goto restart; | ||
2725 | } | ||
2726 | ceph_mdsc_put_request(nextreq); /* won't go away */ | ||
2704 | } | 2727 | } |
2705 | if (!n) | 2728 | req = nextreq; |
2706 | break; | ||
2707 | req = rb_entry(n, struct ceph_mds_request, r_node); | ||
2708 | } | 2729 | } |
2709 | mutex_unlock(&mdsc->mutex); | 2730 | mutex_unlock(&mdsc->mutex); |
2710 | dout("wait_unsafe_requests done\n"); | 2731 | dout("wait_unsafe_requests done\n"); |