[SCSI] make blk layer set REQ_SOFTBARRIER on defer and requeue
authorTejun Heo <htejun@gmail.com>
Sun, 24 Apr 2005 07:04:21 +0000 (02:04 -0500)
committerJames Bottomley <jejb@mulgrave.(none)>
Fri, 20 May 2005 17:53:26 +0000 (12:53 -0500)
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>
drivers/block/elevator.c

index 6b79b4314622053858e17598c50dda88496f06fa..8c51d1ccebbd6c14c20b160e126363f4f06476ab 100644 (file)
@@ -290,6 +290,13 @@ void elv_requeue_request(request_queue_t *q, struct request *rq)
                rq = rq->end_io_data;
        }
 
+       /*
+        * 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) {