summaryrefslogtreecommitdiffstats
path: root/drivers/block/elevator.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2005-04-24 02:04:21 -0500
committerJames Bottomley <jejb@mulgrave.(none)>2005-05-20 12:53:26 -0500
commit2e759cd4fa60c6df4cb117848274f444c2c0a12d (patch)
tree973c2fd1725208de2d0a0ccd99b9fadd93a845fc /drivers/block/elevator.c
parent354d6b2196c8e53e55e8f169804256ab9c72731d (diff)
[SCSI] make blk layer set REQ_SOFTBARRIER on defer and requeue
This is the reworked version of the patch. It sets REQ_SOFTBARRIER in two places - in elv_next_request() on BLKPREP_DEFER and in blk_requeue_request(). Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/block/elevator.c')
-rw-r--r--drivers/block/elevator.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c
index 6b79b431462..8c51d1ccebb 100644
--- a/drivers/block/elevator.c
+++ b/drivers/block/elevator.c
@@ -291,6 +291,13 @@ void elv_requeue_request(request_queue_t *q, struct request *rq)
}
/*
+ * the request is prepped and may have some resources allocated.
+ * allowing unprepped requests to pass this one may cause resource
+ * deadlock. turn on softbarrier.
+ */
+ rq->flags |= REQ_SOFTBARRIER;
+
+ /*
* if iosched has an explicit requeue hook, then use that. otherwise
* just put the request at the front of the queue
*/
@@ -386,6 +393,12 @@ struct request *elv_next_request(request_queue_t *q)
if (ret == BLKPREP_OK) {
break;
} else if (ret == BLKPREP_DEFER) {
+ /*
+ * the request may have been (partially) prepped.
+ * we need to keep this request in the front to
+ * avoid resource deadlock. turn on softbarrier.
+ */
+ rq->flags |= REQ_SOFTBARRIER;
rq = NULL;
break;
} else if (ret == BLKPREP_KILL) {