Add checking to verify all osd requests for an osd are added to the queue in order of increasing tid. Signed-off-by: Alex Elder <elder@xxxxxxxxxxx> --- net/ceph/osd_client.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 4d98424..b059cf6 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -563,6 +563,41 @@ __lookup_request_ge(struct ceph_osd_client *osdc, return NULL; } +#define list_last_entry(ptr, type, member) \ + list_entry((ptr)->prev, type, member) + +/* + * Returns true if it's OK to move the given request to the + * the osd client's unsent list. Called before moving the + * request to the beginning of the list (prepend == true) or + * to the end (prepend == * false). + */ +static bool osdc_unsent_check(struct ceph_osd_client *osdc, + struct ceph_osd_request *req, + bool prepend) +{ + struct ceph_osd_request *list_req; + int bad; + + if (list_empty(&osdc->req_unsent)) + return true; + + if (prepend) { + list_req = list_first_entry(&osdc->req_unsent, + struct ceph_osd_request, + r_req_lru_item); + bad = WARN_ON(req->r_tid > list_req->r_tid); + } else { + list_req = list_last_entry(&osdc->req_unsent, + struct ceph_osd_request, + r_req_lru_item); + bad = WARN_ON(req->r_tid < list_req->r_tid); + } + bad = bad || WARN_ON(req->r_tid == list_req->r_tid); + + return !bad; +} + /* * Resubmit requests pending on the given osd. */ @@ -585,6 +620,7 @@ static void __kick_osd_requests(struct ceph_osd_client *osdc, * in the osd client unsent list in increasing order of tid. */ list_for_each_entry_reverse(req, &osd->o_requests, r_osd_item) { + osdc_unsent_check(osdc, req, true); list_move(&req->r_req_lru_item, &osdc->req_unsent); dout("requeued %p tid %llu osd%d\n", req, req->r_tid, osd->o_osd); @@ -605,6 +641,7 @@ static void __kick_osd_requests(struct ceph_osd_client *osdc, */ BUG_ON(!list_empty(&req->r_req_lru_item)); __register_request(osdc, req); + osdc_unsent_check(osdc, req, false); list_add_tail(&req->r_req_lru_item, &osdc->req_unsent); list_add_tail(&req->r_osd_item, &req->r_osd->o_requests); __unregister_linger_request(osdc, req); @@ -1023,6 +1060,7 @@ static int __map_request(struct ceph_osd_client *osdc, if (req->r_osd) { __remove_osd_from_lru(req->r_osd); list_add_tail(&req->r_osd_item, &req->r_osd->o_requests); + osdc_unsent_check(osdc, req, false); list_move_tail(&req->r_req_lru_item, &osdc->req_unsent); } else { list_move_tail(&req->r_req_lru_item, &osdc->req_notarget); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe ceph-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html