Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=40b01b9bbdf51ae543a04744283bf2d56c4a6afa
Commit:     40b01b9bbdf51ae543a04744283bf2d56c4a6afa
Parent:     56c819df77f96c3fc0c2a979e12b478403728790
Author:     Tejun Heo <[EMAIL PROTECTED]>
AuthorDate: Tue Feb 19 11:35:38 2008 +0100
Committer:  Jens Axboe <[EMAIL PROTECTED]>
CommitDate: Tue Feb 19 11:35:38 2008 +0100

    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 <[EMAIL PROTECTED]>
    Cc: James Bottomley <[EMAIL PROTECTED]>
    Signed-off-by: Jens Axboe <[EMAIL PROTECTED]>
---
 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 bc5ce60..a7cf63c 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,
                ubuf += ret;
        }
 
+       /*
+        * __blk_rq_map_user() copies the buffers if starting address
+        * or length isn't aligned.  As the copied buffer is always
+        * page aligned, we know that there's enough room for padding.
+        * Extend the last bio and update rq->data_len accordingly.
+        *
+        * On unmap, bio_uncopy_user() will use unmodified
+        * bio_map_data pointed to by bio->bi_private.
+        */
+       if (len & queue_dma_alignment(q)) {
+               unsigned int pad_len = (queue_dma_alignment(q) & ~len) + 1;
+               struct bio *bio = rq->biotail;
+
+               bio->bi_io_vec[bio->bi_vcnt - 1].bv_len += pad_len;
+               bio->bi_size += pad_len;
+       }
+
        rq->buffer = rq->data = NULL;
        return 0;
 unmap_rq:
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to