Commit 0717c0a9 authored by Jens Axboe's avatar Jens Axboe

[PATCH] make queue prep_rq_fn() a bit more powerful

Extend q->prep_rq_fn() to return one of three values:

 o BLKPREP_OK: request is good, return it
 o BLKPREP_KILL: request is bad, end it completely
 o BLKPREP_DEFER: request is good, but we can't take it now

We maintain compatability with old prep functions (if any, outside of
ide-cd). This change is needed or SCSI to use prep function for command
init, if sg table allocation fails we can just defer the request.
parent 8c1f67fa
...@@ -303,8 +303,14 @@ static inline struct request *__elv_next_request(request_queue_t *q) ...@@ -303,8 +303,14 @@ static inline struct request *__elv_next_request(request_queue_t *q)
struct request *elv_next_request(request_queue_t *q) struct request *elv_next_request(request_queue_t *q)
{ {
struct request *rq; struct request *rq;
int ret;
while ((rq = __elv_next_request(q))) { while ((rq = __elv_next_request(q))) {
/*
* just mark as started even if we don't start it, a request
* that has been delayed should not be passed by new incoming
* requests
*/
rq->flags |= REQ_STARTED; rq->flags |= REQ_STARTED;
if (&rq->queuelist == q->last_merge) if (&rq->queuelist == q->last_merge)
...@@ -313,20 +319,22 @@ struct request *elv_next_request(request_queue_t *q) ...@@ -313,20 +319,22 @@ struct request *elv_next_request(request_queue_t *q)
if ((rq->flags & REQ_DONTPREP) || !q->prep_rq_fn) if ((rq->flags & REQ_DONTPREP) || !q->prep_rq_fn)
break; break;
/* ret = q->prep_rq_fn(q, rq);
* all ok, break and return it if (ret == BLKPREP_OK) {
*/
if (!q->prep_rq_fn(q, rq))
break; break;
} else if (ret == BLKPREP_DEFER) {
/* rq = NULL;
* prep said no-go, kill it break;
*/ } else if (ret == BLKPREP_KILL) {
blkdev_dequeue_request(rq); blkdev_dequeue_request(rq);
if (end_that_request_first(rq, 0, rq->nr_sectors)) rq->flags |= REQ_QUIET;
BUG(); while (end_that_request_first(rq, 0, rq->nr_sectors))
;
end_that_request_last(rq); end_that_request_last(rq);
} else {
printk("%s: bad return=%d\n", __FUNCTION__, ret);
break;
}
} }
return rq; return rq;
......
...@@ -254,6 +254,13 @@ struct request_queue ...@@ -254,6 +254,13 @@ struct request_queue
*/ */
#define blk_queue_headactive(q, head_active) #define blk_queue_headactive(q, head_active)
/*
* q->prep_rq_fn return values
*/
#define BLKPREP_OK 0 /* serve it */
#define BLKPREP_KILL 1 /* fatal error, kill */
#define BLKPREP_DEFER 2 /* leave on queue */
extern unsigned long blk_max_low_pfn, blk_max_pfn; extern unsigned long blk_max_low_pfn, blk_max_pfn;
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment