[PATCH] block: fix bio_add_page misuse with rq_map_data

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This fixes bio_add_page misuse in bio_copy_user_iov with rq_map_data,
which only sg uses now.

rq_map_data carries page frames for bio_add_pc_page. bio_copy_user_iov
uses bio_add_pc_page with a larger size than PAGE_SIZE. it's clearly
wrong, though it works if a request doesn't go to the bounce path, I
think.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@xxxxxxxxxxxxx>
---
 fs/bio.c |   19 +++++++++++--------
 1 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/fs/bio.c b/fs/bio.c
index 77a55bc..0ebf768 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -662,23 +662,26 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
 
 	ret = 0;
 	i = 0;
+	if (map_data)
+		nr_pages = 1 << map_data->page_order;
 	while (len) {
-		unsigned int bytes;
-
-		if (map_data)
-			bytes = 1U << (PAGE_SHIFT + map_data->page_order);
-		else
-			bytes = PAGE_SIZE;
+		unsigned int bytes = PAGE_SIZE;
 
 		if (bytes > len)
 			bytes = len;
 
 		if (map_data) {
-			if (i == map_data->nr_entries) {
+			if (i == map_data->nr_entries * nr_pages) {
 				ret = -ENOMEM;
 				break;
 			}
-			page = map_data->pages[i++];
+
+			if (i && (i % nr_pages))
+				page++;
+			else
+				page = map_data->pages[i / nr_pages];
+
+			i++;
 		} else
 			page = alloc_page(q->bounce_gfp | gfp_mask);
 		if (!page) {
-- 
1.5.5.GIT

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux