# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.814 -> 1.815 # include/linux/blkdev.h 1.77 -> 1.78 # drivers/block/elevator.c 1.30 -> 1.31 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/10/28 axboe@burns.home.kernel.dk 1.815 # 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. # -------------------------------------------- # diff -Nru a/drivers/block/elevator.c b/drivers/block/elevator.c --- a/drivers/block/elevator.c Mon Oct 28 18:01:23 2002 +++ b/drivers/block/elevator.c Mon Oct 28 18:01:23 2002 @@ -303,8 +303,14 @@ struct request *elv_next_request(request_queue_t *q) { struct request *rq; + int ret; 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; if (&rq->queuelist == q->last_merge) @@ -313,20 +319,22 @@ if ((rq->flags & REQ_DONTPREP) || !q->prep_rq_fn) break; - /* - * all ok, break and return it - */ - if (!q->prep_rq_fn(q, rq)) + ret = q->prep_rq_fn(q, rq); + if (ret == BLKPREP_OK) { break; - - /* - * prep said no-go, kill it - */ - blkdev_dequeue_request(rq); - if (end_that_request_first(rq, 0, rq->nr_sectors)) - BUG(); - - end_that_request_last(rq); + } else if (ret == BLKPREP_DEFER) { + rq = NULL; + break; + } else if (ret == BLKPREP_KILL) { + blkdev_dequeue_request(rq); + rq->flags |= REQ_QUIET; + while (end_that_request_first(rq, 0, rq->nr_sectors)) + ; + end_that_request_last(rq); + } else { + printk("%s: bad return=%d\n", __FUNCTION__, ret); + break; + } } return rq; diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h --- a/include/linux/blkdev.h Mon Oct 28 18:01:23 2002 +++ b/include/linux/blkdev.h Mon Oct 28 18:01:23 2002 @@ -254,6 +254,13 @@ */ #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; /*