diff options
Diffstat (limited to 'block/elevator.c')
-rw-r--r-- | block/elevator.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/block/elevator.c b/block/elevator.c index f9736fbdab03..8cd5775acd7a 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
@@ -741,7 +741,21 @@ struct request *elv_next_request(struct request_queue *q) | |||
741 | q->boundary_rq = NULL; | 741 | q->boundary_rq = NULL; |
742 | } | 742 | } |
743 | 743 | ||
744 | if ((rq->cmd_flags & REQ_DONTPREP) || !q->prep_rq_fn) | 744 | if (rq->cmd_flags & REQ_DONTPREP) |
745 | break; | ||
746 | |||
747 | if (q->dma_drain_size && rq->data_len) { | ||
748 | /* | ||
749 | * make sure space for the drain appears we | ||
750 | * know we can do this because max_hw_segments | ||
751 | * has been adjusted to be one fewer than the | ||
752 | * device can handle | ||
753 | */ | ||
754 | rq->nr_phys_segments++; | ||
755 | rq->nr_hw_segments++; | ||
756 | } | ||
757 | |||
758 | if (!q->prep_rq_fn) | ||
745 | break; | 759 | break; |
746 | 760 | ||
747 | ret = q->prep_rq_fn(q, rq); | 761 | ret = q->prep_rq_fn(q, rq); |
@@ -754,6 +768,16 @@ struct request *elv_next_request(struct request_queue *q) | |||
754 | * avoid resource deadlock. REQ_STARTED will | 768 | * avoid resource deadlock. REQ_STARTED will |
755 | * prevent other fs requests from passing this one. | 769 | * prevent other fs requests from passing this one. |
756 | */ | 770 | */ |
771 | if (q->dma_drain_size && rq->data_len && | ||
772 | !(rq->cmd_flags & REQ_DONTPREP)) { | ||
773 | /* | ||
774 | * remove the space for the drain we added | ||
775 | * so that we don't add it again | ||
776 | */ | ||
777 | --rq->nr_phys_segments; | ||
778 | --rq->nr_hw_segments; | ||
779 | } | ||
780 | |||
757 | rq = NULL; | 781 | rq = NULL; |
758 | break; | 782 | break; |
759 | } else if (ret == BLKPREP_KILL) { | 783 | } else if (ret == BLKPREP_KILL) { |