From: Jake Wires Date: Thu, 1 Jul 2010 19:29:06 +0000 (-0700) Subject: don't retry when there's no point X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=9a3bcd260fd7eb92bcca4b1772c0ddae50b6ab29;p=people%2Fdstodden%2Fblktap.git don't retry when there's no point Signed-off-by: Jake Wires --- diff --git a/drivers/tapdisk-image.c b/drivers/tapdisk-image.c index 96ebd4b..f26b6d4 100644 --- a/drivers/tapdisk-image.c +++ b/drivers/tapdisk-image.c @@ -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; } diff --git a/drivers/tapdisk-vbd.c b/drivers/tapdisk-vbd.c index 4a11a30..b885d6e 100644 --- a/drivers/tapdisk-vbd.c +++ b/drivers/tapdisk-vbd.c @@ -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; } diff --git a/drivers/tapdisk-vbd.h b/drivers/tapdisk-vbd.h index 70a0a78..90711ad 100644 --- a/drivers/tapdisk-vbd.h +++ b/drivers/tapdisk-vbd.h @@ -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