]> err.no Git - linux-2.6/blobdiff - drivers/block/elevator.c
Merge with rsync://fileserver/linux
[linux-2.6] / drivers / block / elevator.c
index 98fcabbafe1ea03ebe1fd14e4772e62ea0b8abf3..f831f08f839c14d145cb19d322b361c47a08a2e6 100644 (file)
@@ -285,6 +285,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
@@ -317,7 +324,7 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where,
                        int nrq = q->rq.count[READ] + q->rq.count[WRITE]
                                  - q->in_flight;
 
-                       if (nrq == q->unplug_thresh)
+                       if (nrq >= q->unplug_thresh)
                                __generic_unplug_device(q);
                }
        } else
@@ -381,6 +388,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) {