diff options
| author | Tejun Heo <htejun@gmail.com> | 2008-02-19 05:35:38 -0500 |
|---|---|---|
| committer | Jens Axboe <jens.axboe@oracle.com> | 2008-02-19 05:35:38 -0500 |
| commit | 40b01b9bbdf51ae543a04744283bf2d56c4a6afa (patch) | |
| tree | 0f81015c01834b97fdb5646a63c3fe1a24936d81 | |
| parent | 56c819df77f96c3fc0c2a979e12b478403728790 (diff) | |
block: update bio according to DMA alignment padding
DMA start address and transfer size alignment for PC requests are
achieved using bio_copy_user() instead of bio_map_user(). This works
because bio_copy_user() always uses full pages and block DMA alignment
isn't allowed to go over PAGE_SIZE.
However, the implementation didn't update the last bio of the request
to make this padding visible to lower layers. This patch makes
blk_rq_map_user() extend the last bio such that it includes the
padding area and the size of area pointed to by the request is
properly aligned.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
| -rw-r--r-- | block/blk-map.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/block/blk-map.c b/block/blk-map.c index bc5ce60691..a7cf63ccb5 100644 --- a/block/blk-map.c +++ b/block/blk-map.c | |||
| @@ -139,6 +139,23 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq, | |||
| 139 | ubuf += ret; | 139 | ubuf += ret; |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | /* | ||
| 143 | * __blk_rq_map_user() copies the buffers if starting address | ||
| 144 | * or length isn't aligned. As the copied buffer is always | ||
| 145 | * page aligned, we know that there's enough room for padding. | ||
| 146 | * Extend the last bio and update rq->data_len accordingly. | ||
| 147 | * | ||
| 148 | * On unmap, bio_uncopy_user() will use unmodified | ||
| 149 | * bio_map_data pointed to by bio->bi_private. | ||
| 150 | */ | ||
| 151 | if (len & queue_dma_alignment(q)) { | ||
| 152 | unsigned int pad_len = (queue_dma_alignment(q) & ~len) + 1; | ||
| 153 | struct bio *bio = rq->biotail; | ||
| 154 | |||
| 155 | bio->bi_io_vec[bio->bi_vcnt - 1].bv_len += pad_len; | ||
| 156 | bio->bi_size += pad_len; | ||
| 157 | } | ||
| 158 | |||
| 142 | rq->buffer = rq->data = NULL; | 159 | rq->buffer = rq->data = NULL; |
| 143 | return 0; | 160 | return 0; |
| 144 | unmap_rq: | 161 | unmap_rq: |
