aboutsummaryrefslogtreecommitdiffstats
path: root/net/ceph/osd_client.c
diff options
context:
space:
mode:
authorIlya Dryomov <ilya.dryomov@inktank.com>2014-09-03 06:41:45 -0400
committerIlya Dryomov <idryomov@redhat.com>2014-10-14 13:03:19 -0400
commit2cc6128ab2afff7864dbdc33a73e2deaa935d9e0 (patch)
treeec01f8fa1901e90dd86b79184e680b3b327ad28d /net/ceph/osd_client.c
parentf671b581f1dac61354186b7373af5f97fe420584 (diff)
libceph: resend lingering requests with a new tid
Both not yet registered (r_linger && list_empty(&r_linger_item)) and registered linger requests should use the new tid on resend to avoid the dup op detection logic on the OSDs, yet we were doing this only for "registered" case. Factor out and simplify the "registered" logic and use the new helper for "not registered" case as well. Fixes: http://tracker.ceph.com/issues/8806 Signed-off-by: Ilya Dryomov <ilya.dryomov@inktank.com> Reviewed-by: Alex Elder <elder@linaro.org>
Diffstat (limited to 'net/ceph/osd_client.c')
-rw-r--r--net/ceph/osd_client.c73
1 files changed, 54 insertions, 19 deletions
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 648a215d734e..84b02242b724 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -30,8 +30,11 @@ static void __send_queued(struct ceph_osd_client *osdc);
30static int __reset_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd); 30static int __reset_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd);
31static void __register_request(struct ceph_osd_client *osdc, 31static void __register_request(struct ceph_osd_client *osdc,
32 struct ceph_osd_request *req); 32 struct ceph_osd_request *req);
33static void __unregister_request(struct ceph_osd_client *osdc,
34 struct ceph_osd_request *req);
33static void __unregister_linger_request(struct ceph_osd_client *osdc, 35static void __unregister_linger_request(struct ceph_osd_client *osdc,
34 struct ceph_osd_request *req); 36 struct ceph_osd_request *req);
37static void __enqueue_request(struct ceph_osd_request *req);
35static void __send_request(struct ceph_osd_client *osdc, 38static void __send_request(struct ceph_osd_client *osdc,
36 struct ceph_osd_request *req); 39 struct ceph_osd_request *req);
37 40
@@ -892,6 +895,37 @@ __lookup_request_ge(struct ceph_osd_client *osdc,
892 return NULL; 895 return NULL;
893} 896}
894 897
898static void __kick_linger_request(struct ceph_osd_request *req)
899{
900 struct ceph_osd_client *osdc = req->r_osdc;
901 struct ceph_osd *osd = req->r_osd;
902
903 /*
904 * Linger requests need to be resent with a new tid to avoid
905 * the dup op detection logic on the OSDs. Achieve this with
906 * a re-register dance instead of open-coding.
907 */
908 ceph_osdc_get_request(req);
909 if (!list_empty(&req->r_linger_item))
910 __unregister_linger_request(osdc, req);
911 else
912 __unregister_request(osdc, req);
913 __register_request(osdc, req);
914 ceph_osdc_put_request(req);
915
916 /*
917 * Unless request has been registered as both normal and
918 * lingering, __unregister{,_linger}_request clears r_osd.
919 * However, here we need to preserve r_osd to make sure we
920 * requeue on the same OSD.
921 */
922 WARN_ON(req->r_osd || !osd);
923 req->r_osd = osd;
924
925 dout("%s requeueing %p tid %llu\n", __func__, req, req->r_tid);
926 __enqueue_request(req);
927}
928
895/* 929/*
896 * Resubmit requests pending on the given osd. 930 * Resubmit requests pending on the given osd.
897 */ 931 */
@@ -900,12 +934,14 @@ static void __kick_osd_requests(struct ceph_osd_client *osdc,
900{ 934{
901 struct ceph_osd_request *req, *nreq; 935 struct ceph_osd_request *req, *nreq;
902 LIST_HEAD(resend); 936 LIST_HEAD(resend);
937 LIST_HEAD(resend_linger);
903 int err; 938 int err;
904 939
905 dout("__kick_osd_requests osd%d\n", osd->o_osd); 940 dout("%s osd%d\n", __func__, osd->o_osd);
906 err = __reset_osd(osdc, osd); 941 err = __reset_osd(osdc, osd);
907 if (err) 942 if (err)
908 return; 943 return;
944
909 /* 945 /*
910 * Build up a list of requests to resend by traversing the 946 * Build up a list of requests to resend by traversing the
911 * osd's list of requests. Requests for a given object are 947 * osd's list of requests. Requests for a given object are
@@ -926,33 +962,32 @@ static void __kick_osd_requests(struct ceph_osd_client *osdc,
926 list_for_each_entry(req, &osd->o_requests, r_osd_item) { 962 list_for_each_entry(req, &osd->o_requests, r_osd_item) {
927 if (!req->r_sent) 963 if (!req->r_sent)
928 break; 964 break;
929 list_move_tail(&req->r_req_lru_item, &resend); 965
930 dout("requeueing %p tid %llu osd%d\n", req, req->r_tid, 966 if (!req->r_linger) {
931 osd->o_osd); 967 dout("%s requeueing %p tid %llu\n", __func__, req,
932 if (!req->r_linger) 968 req->r_tid);
969 list_move_tail(&req->r_req_lru_item, &resend);
933 req->r_flags |= CEPH_OSD_FLAG_RETRY; 970 req->r_flags |= CEPH_OSD_FLAG_RETRY;
971 } else {
972 list_move_tail(&req->r_req_lru_item, &resend_linger);
973 }
934 } 974 }
935 list_splice(&resend, &osdc->req_unsent); 975 list_splice(&resend, &osdc->req_unsent);
936 976
937 /* 977 /*
938 * Linger requests are re-registered before sending, which 978 * Both registered and not yet registered linger requests are
939 * sets up a new tid for each. We add them to the unsent 979 * enqueued with a new tid on the same OSD. We add/move them
940 * list at the end to keep things in tid order. 980 * to req_unsent/o_requests at the end to keep things in tid
981 * order.
941 */ 982 */
942 list_for_each_entry_safe(req, nreq, &osd->o_linger_requests, 983 list_for_each_entry_safe(req, nreq, &osd->o_linger_requests,
943 r_linger_osd_item) { 984 r_linger_osd_item) {
944 /* 985 WARN_ON(!list_empty(&req->r_req_lru_item));
945 * reregister request prior to unregistering linger so 986 __kick_linger_request(req);
946 * that r_osd is preserved.
947 */
948 BUG_ON(!list_empty(&req->r_req_lru_item));
949 __register_request(osdc, req);
950 list_add_tail(&req->r_req_lru_item, &osdc->req_unsent);
951 list_add_tail(&req->r_osd_item, &req->r_osd->o_requests);
952 __unregister_linger_request(osdc, req);
953 dout("requeued lingering %p tid %llu osd%d\n", req, req->r_tid,
954 osd->o_osd);
955 } 987 }
988
989 list_for_each_entry_safe(req, nreq, &resend_linger, r_req_lru_item)
990 __kick_linger_request(req);
956} 991}
957 992
958/* 993/*