]> xenbits.xensource.com Git - people/dstodden/blktap.git/commitdiff
don't retry when there's no point
authorJake Wires <jake.wires@citrix.com>
Thu, 1 Jul 2010 19:29:06 +0000 (12:29 -0700)
committerJake Wires <jake.wires@citrix.com>
Thu, 1 Jul 2010 19:29:06 +0000 (12:29 -0700)
Signed-off-by: Jake Wires <jake.wires@citrix.com>
drivers/tapdisk-image.c
drivers/tapdisk-vbd.c
drivers/tapdisk-vbd.h

index 96ebd4b6435d6d9e9c0dd9a408554f2c4eee29bf..f26b6d4ff018c873890bf95cdf202c170b757fee 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,8 +160,8 @@ 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;
 }
index 4a11a30f04fd9262f10dbf35f54922f38c109bb9..b885d6e120ff84729569331bdc445e65c7a00ab5 100644 (file)
@@ -1060,7 +1060,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
@@ -1425,14 +1426,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);
@@ -1605,12 +1625,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++) {
@@ -1672,6 +1696,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)
 {
@@ -1705,11 +1735,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 int
@@ -1720,7 +1754,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;
        }
 
index 70a0a78255b5a1c83e86eeaf6abe455a49f29e0f..90711add6eb2fd8ff431dc5de6bf8049489b3290 100644 (file)
@@ -77,6 +77,7 @@ struct td_vbd_request {
 
        td_vbd_t                   *vbd;
        struct list_head            next;
+       struct list_head           *list_head;
 };
 
 struct td_vbd_handle {
@@ -137,6 +138,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