]> xenbits.xensource.com Git - people/dstodden/blktap.git/commitdiff
CA-29373: Don't retry when there's no point, batched.
authorJake Wires <Jake.Wires@citrix.com>
Tue, 15 Feb 2011 09:37:44 +0000 (01:37 -0800)
committerJake Wires <Jake.Wires@citrix.com>
Tue, 15 Feb 2011 09:37:44 +0000 (01:37 -0800)
Date: Thu, 1 Jul 2010 11:33:47 -0700
[PATCH 68/79] don't retry when there's no point
[PATCH 69/79] fix handling early failures

Signed-off-by: Jake Wires <jake.wires@citrix.com>
Acked-by: Daniel Stodden <daniel.stodden@citrix.com>
drivers/tapdisk-image.c
drivers/tapdisk-vbd.c
drivers/tapdisk-vbd.h

index 43c633b38949b160b07d6aef915fd07c8d6dffa1..6d6f38d0cdfff415d229fc79947330df836e23f5 100644 (file)
@@ -77,10 +77,12 @@ tapdisk_image_free(td_image_t *image)
 int
 tapdisk_image_check_td_request(td_image_t *image, td_request_t treq)
 {
-       int rdonly;
+       int rdonly, err;
        td_driver_t *driver;
        td_disk_info_t *info;
 
+       err = -EINVAL;
+
        driver = image->driver;
        if (!driver)
                return -ENODEV;
@@ -91,8 +93,10 @@ tapdisk_image_check_td_request(td_image_t *image, td_request_t treq)
        if (treq.op != TD_OP_READ && treq.op != TD_OP_WRITE)
                goto fail;
 
-       if (treq.op == TD_OP_WRITE && rdonly)
+       if (treq.op == TD_OP_WRITE && rdonly) {
+               err = -EPERM;
                goto fail;
+       }
 
        if (treq.secs <= 0 || treq.sec + treq.secs > info->size)
                goto fail;
@@ -100,10 +104,10 @@ tapdisk_image_check_td_request(td_image_t *image, td_request_t treq)
        return 0;
 
 fail:
-       ERR(-EINVAL, "bad td request on %s (%s, %llu): %d at %llu",
+       ERR(err, "bad td request on %s (%s, %llu): %d at %llu",
            image->name, (rdonly ? "ro" : "rw"), info->size, treq.op,
            treq.sec + treq.secs);
-       return -EINVAL;
+       return err;
 
 }
 
@@ -112,13 +116,14 @@ tapdisk_image_check_ring_request(td_image_t *image, blkif_request_t *req)
 {
        td_driver_t *driver;
        td_disk_info_t *info;
-       int i, psize, rdonly;
        uint64_t nsects, total;
+       int i, err, psize, rdonly;
 
        driver = image->driver;
        if (!driver)
                return -ENODEV;
 
+       err    = -EINVAL;
        nsects = 0;
        total  = 0;
        info   = &driver->info;
@@ -129,8 +134,10 @@ tapdisk_image_check_ring_request(td_image_t *image, blkif_request_t *req)
            req->operation != BLKIF_OP_WRITE)
                goto fail;
 
-       if (req->operation == BLKIF_OP_WRITE && rdonly)
+       if (req->operation == BLKIF_OP_WRITE && rdonly) {
+               err = -EPERM;
                goto fail;
+       }
 
        if (!req->nr_segments || req->nr_segments > MAX_SEGMENTS_PER_REQ)
                goto fail;
@@ -153,10 +160,10 @@ tapdisk_image_check_ring_request(td_image_t *image, blkif_request_t *req)
        return 0;
 
 fail:
-       ERR(-EINVAL, "bad request on %s (%s, %llu): id: %llu: %d at %llu",
+       ERR(err, "bad request on %s (%s, %llu): id: %llu: %d at %llu",
            image->name, (rdonly ? "ro" : "rw"), info->size, req->id,
            req->operation, req->sector_number + total);
-       return -EINVAL;
+       return err;
 }
 
 void
index 17c08533d810c9f51ac6564c05e093c838c0ec53..3c188ad263afe1c5ede71afa0b12288c1ca5b62c 100644 (file)
@@ -946,7 +946,8 @@ tapdisk_vbd_queue_ready(td_vbd_t *vbd)
 int
 tapdisk_vbd_retry_needed(td_vbd_t *vbd)
 {
-       return !list_empty(&vbd->failed_requests);
+       return !(list_empty(&vbd->failed_requests) ||
+                list_empty(&vbd->new_requests));
 }
 
 int
@@ -1275,14 +1276,33 @@ tapdisk_vbd_check_queue(td_vbd_t *vbd)
        return 0;
 }
 
+static int
+tapdisk_vbd_request_should_retry(td_vbd_t *vbd, td_vbd_request_t *vreq)
+{
+       if (td_flag_test(vbd->state, TD_VBD_DEAD) ||
+           td_flag_test(vbd->state, TD_VBD_SHUTDOWN_REQUESTED))
+               return 0;
+
+       switch (abs(vreq->error)) {
+       case EPERM:
+       case ENOSYS:
+       case ESTALE:
+       case ENOSPC:
+               return 0;
+       }
+
+       if (tapdisk_vbd_request_timeout(vreq))
+               return 0;
+
+       return 1;
+}
+
 static void
 tapdisk_vbd_complete_vbd_request(td_vbd_t *vbd, td_vbd_request_t *vreq)
 {
        if (!vreq->submitting && !vreq->secs_pending) {
                if (vreq->status == BLKIF_RSP_ERROR &&
-                   !tapdisk_vbd_request_timeout(vreq) &&
-                   !td_flag_test(vbd->state, TD_VBD_DEAD) &&
-                   !td_flag_test(vbd->state, TD_VBD_SHUTDOWN_REQUESTED))
+                   tapdisk_vbd_request_should_retry(vbd, vreq))
                        tapdisk_vbd_move_request(vreq, &vbd->failed_requests);
                else
                        tapdisk_vbd_move_request(vreq, &vbd->completed_requests);
@@ -1511,12 +1531,16 @@ tapdisk_vbd_issue_request(td_vbd_t *vbd, td_vbd_request_t *vreq)
        tapdisk_vbd_move_request(vreq, &vbd->pending_requests);
 
        err = tapdisk_vbd_check_queue(vbd);
-       if (err)
+       if (err) {
+               vreq->error = err;
                goto fail;
+       }
 
        err = tapdisk_image_check_ring_request(image, req);
-       if (err)
+       if (err) {
+               vreq->error = err;
                goto fail;
+       }
 
        memset(&treq, 0, sizeof(td_request_t));
        for (i = 0; i < req->nr_segments; i++) {
@@ -1583,6 +1607,12 @@ fail:
        goto out;
 }
 
+static int
+tapdisk_vbd_request_completed(td_vbd_t *vbd, td_vbd_request_t *vreq)
+{
+       return vreq->list_head == &vbd->completed_requests;
+}
+
 static int
 tapdisk_vbd_reissue_failed_requests(td_vbd_t *vbd)
 {
@@ -1616,11 +1646,15 @@ tapdisk_vbd_reissue_failed_requests(td_vbd_t *vbd)
                    vreq->req.nr_segments);
 
                err = tapdisk_vbd_issue_request(vbd, vreq);
-               if (err)
+               /*
+                * if this request failed, but was not completed,
+                * we'll back off for a while.
+                */
+               if (err && !tapdisk_vbd_request_completed(vbd, vreq))
                        break;
        }
 
-       return err;
+       return 0;
 }
 
 static void
@@ -1646,7 +1680,11 @@ tapdisk_vbd_issue_new_requests(td_vbd_t *vbd)
 
        tapdisk_vbd_for_each_request(vreq, tmp, &vbd->new_requests) {
                err = tapdisk_vbd_issue_request(vbd, vreq);
-               if (err)
+               /*
+                * if this request failed, but was not completed,
+                * we'll back off for a while.
+                */
+               if (err && !tapdisk_vbd_request_completed(vbd, vreq))
                        return err;
 
                tapdisk_vbd_count_new_request(vbd, vreq);
index d8e0f8a21ca47c9da085afc055f6ed0da63b59fe..e1c3ef57587e0e700c08b8e59dfcfaada5980998 100644 (file)
@@ -79,6 +79,7 @@ struct td_vbd_request {
 
        td_vbd_t                   *vbd;
        struct list_head            next;
+       struct list_head           *list_head;
 };
 
 struct td_vbd_handle {
@@ -150,6 +151,7 @@ tapdisk_vbd_move_request(td_vbd_request_t *vreq, struct list_head *dest)
        list_del(&vreq->next);
        INIT_LIST_HEAD(&vreq->next);
        list_add_tail(&vreq->next, dest);
+       vreq->list_head = dest;
 }
 
 static inline void