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 <[email protected]>
---
 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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to