summaryrefslogtreecommitdiff
path: root/fs/bio.c
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2008-12-18 14:49:37 +0900
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-01-02 11:10:08 -0600
commit56c451f4b583ccdf80c9e676179c9cb49de86745 (patch)
tree7ad9daeafb88e3c4390bf7a2db0c203fe2642728 /fs/bio.c
parente623ddb4e940b266adc77ba1cc28a3554aa90e79 (diff)
downloadlinux-stable-56c451f4b583ccdf80c9e676179c9cb49de86745.tar.gz
linux-stable-56c451f4b583ccdf80c9e676179c9cb49de86745.tar.bz2
linux-stable-56c451f4b583ccdf80c9e676179c9cb49de86745.zip
[SCSI] block: fix the partial mappings with struct rq_map_data
This fixes bio_copy_user_iov to properly handle the partial mappings with struct rq_map_data (which only sg uses for now but st and osst will shortly). It adds the offset member to struct rq_map_data and changes blk_rq_map_user to update it so that bio_copy_user_iov can add an appropriate page frame via bio_add_pc_page(). Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Acked-by: Jens Axboe <jens.axboe@oracle.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'fs/bio.c')
-rw-r--r--fs/bio.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/fs/bio.c b/fs/bio.c
index 356e7423b923..13be075806b6 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -788,6 +788,7 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
int i, ret;
int nr_pages = 0;
unsigned int len = 0;
+ unsigned int offset = map_data ? map_data->offset & ~PAGE_MASK : 0;
for (i = 0; i < iov_count; i++) {
unsigned long uaddr;
@@ -814,12 +815,16 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
bio->bi_rw |= (!write_to_vm << BIO_RW);
ret = 0;
- i = 0;
- if (map_data)
+
+ if (map_data) {
nr_pages = 1 << map_data->page_order;
+ i = map_data->offset / PAGE_SIZE;
+ }
while (len) {
unsigned int bytes = PAGE_SIZE;
+ bytes -= offset;
+
if (bytes > len)
bytes = len;
@@ -841,10 +846,11 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
}
}
- if (bio_add_pc_page(q, bio, page, bytes, 0) < bytes)
+ if (bio_add_pc_page(q, bio, page, bytes, offset) < bytes)
break;
len -= bytes;
+ offset = 0;
}
if (ret)