aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/blk-map.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/block/blk-map.c b/block/blk-map.c
index bc5ce60691c3..a7cf63ccb5cf 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;
144unmap_rq: 161unmap_rq: