rpms/kernel/F-9 linux-2.6-bio-fix-__bio_copy_iov-handling-of-bv_len.patch, NONE, 1.1 linux-2.6-bio-fix-bio_copy_kern-handling-of-bv_len.patch, NONE, 1.1 kernel.spec, 1.749, 1.750

Chuck Ebbert cebbert at fedoraproject.org
Sun Aug 31 01:23:26 UTC 2008


Author: cebbert

Update of /cvs/pkgs/rpms/kernel/F-9
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv10112

Modified Files:
	kernel.spec 
Added Files:
	linux-2.6-bio-fix-__bio_copy_iov-handling-of-bv_len.patch 
	linux-2.6-bio-fix-bio_copy_kern-handling-of-bv_len.patch 
Log Message:
Add two bio patches scheduled for -stable.

linux-2.6-bio-fix-__bio_copy_iov-handling-of-bv_len.patch:

--- NEW FILE linux-2.6-bio-fix-__bio_copy_iov-handling-of-bv_len.patch ---
From: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
Date: Mon, 25 Aug 2008 18:36:08 +0000 (+0200)
Subject: bio: fix __bio_copy_iov() handling of bio->bv_len
X-Git-Tag: v2.6.27-rc5~19^2~2
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=aefcc28a3a63ac33a298777aa50ba43641c75241

bio: fix __bio_copy_iov() handling of bio->bv_len

The commit c5dec1c3034f1ae3503efbf641ff3b0273b64797 introduced
__bio_copy_iov() to add bounce support to blk_rq_map_user_iov.

__bio_copy_iov() uses bio->bv_len to copy data for READ commands after
the completion but it doesn't work with a request that partially
completed. SCSI always completes a PC request as a whole but seems
some don't.

Signed-off-by: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
Cc: stable at kernel.org
Signed-off-by: Jens Axboe <jens.axboe at oracle.com>
---

diff --git a/fs/bio.c b/fs/bio.c
index 8b1f5ee..3cba7ae 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -492,8 +492,8 @@ static struct bio_map_data *bio_alloc_map_data(int nr_segs, int iov_count,
 	return NULL;
 }
 
-static int __bio_copy_iov(struct bio *bio, struct sg_iovec *iov, int iov_count,
-			  int uncopy)
+static int __bio_copy_iov(struct bio *bio, struct bio_vec *iovecs,
+			  struct sg_iovec *iov, int iov_count, int uncopy)
 {
 	int ret = 0, i;
 	struct bio_vec *bvec;
@@ -503,7 +503,7 @@ static int __bio_copy_iov(struct bio *bio, struct sg_iovec *iov, int iov_count,
 
 	__bio_for_each_segment(bvec, bio, i, 0) {
 		char *bv_addr = page_address(bvec->bv_page);
-		unsigned int bv_len = bvec->bv_len;
+		unsigned int bv_len = iovecs[i].bv_len;
 
 		while (bv_len && iov_idx < iov_count) {
 			unsigned int bytes;
@@ -555,7 +555,7 @@ int bio_uncopy_user(struct bio *bio)
 	struct bio_map_data *bmd = bio->bi_private;
 	int ret;
 
-	ret = __bio_copy_iov(bio, bmd->sgvecs, bmd->nr_sgvecs, 1);
+	ret = __bio_copy_iov(bio, bmd->iovecs, bmd->sgvecs, bmd->nr_sgvecs, 1);
 
 	bio_free_map_data(bmd);
 	bio_put(bio);
@@ -634,7 +634,7 @@ struct bio *bio_copy_user_iov(struct request_queue *q, struct sg_iovec *iov,
 	 * success
 	 */
 	if (!write_to_vm) {
-		ret = __bio_copy_iov(bio, iov, iov_count, 0);
+		ret = __bio_copy_iov(bio, bio->bi_io_vec, iov, iov_count, 0);
 		if (ret)
 			goto cleanup;
 	}

linux-2.6-bio-fix-bio_copy_kern-handling-of-bv_len.patch:

--- NEW FILE linux-2.6-bio-fix-bio_copy_kern-handling-of-bv_len.patch ---
From: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
Date: Mon, 25 Aug 2008 18:36:08 +0000 (+0200)
Subject: bio: fix bio_copy_kern() handling of bio->bv_len
X-Git-Tag: v2.6.27-rc5~19^2~3
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=76029ff37f31dad64641489c610d98955217bb68

bio: fix bio_copy_kern() handling of bio->bv_len

The commit 68154e90c9d1492d570671ae181d9a8f8530da55 introduced
bio_copy_kern() to add bounce support to blk_rq_map_kern.

bio_copy_kern() uses bio->bv_len to copy data for READ commands after
the completion but it doesn't work with a request that partially
completed. SCSI always completes a PC request as a whole but seems
some don't.

This patch fixes bio_copy_kern to handle the above case. As
bio_copy_user does, bio_copy_kern uses struct bio_map_data to store
struct bio_vec.

Signed-off-by: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
Reported-by: Nix <nix at esperi.org.uk>
Tested-by: Nix <nix at esperi.org.uk>
Cc: stable at kernel.org
Signed-off-by: Jens Axboe <jens.axboe at oracle.com>
---

diff --git a/fs/bio.c b/fs/bio.c
index 8000e2f..8b1f5ee 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -469,20 +469,21 @@ static void bio_free_map_data(struct bio_map_data *bmd)
 	kfree(bmd);
 }
 
-static struct bio_map_data *bio_alloc_map_data(int nr_segs, int iov_count)
+static struct bio_map_data *bio_alloc_map_data(int nr_segs, int iov_count,
+					       gfp_t gfp_mask)
 {
-	struct bio_map_data *bmd = kmalloc(sizeof(*bmd), GFP_KERNEL);
+	struct bio_map_data *bmd = kmalloc(sizeof(*bmd), gfp_mask);
 
 	if (!bmd)
 		return NULL;
 
-	bmd->iovecs = kmalloc(sizeof(struct bio_vec) * nr_segs, GFP_KERNEL);
+	bmd->iovecs = kmalloc(sizeof(struct bio_vec) * nr_segs, gfp_mask);
 	if (!bmd->iovecs) {
 		kfree(bmd);
 		return NULL;
 	}
 
-	bmd->sgvecs = kmalloc(sizeof(struct sg_iovec) * iov_count, GFP_KERNEL);
+	bmd->sgvecs = kmalloc(sizeof(struct sg_iovec) * iov_count, gfp_mask);
 	if (bmd->sgvecs)
 		return bmd;
 
@@ -596,7 +597,7 @@ struct bio *bio_copy_user_iov(struct request_queue *q, struct sg_iovec *iov,
 		len += iov[i].iov_len;
 	}
 
-	bmd = bio_alloc_map_data(nr_pages, iov_count);
+	bmd = bio_alloc_map_data(nr_pages, iov_count, GFP_KERNEL);
 	if (!bmd)
 		return ERR_PTR(-ENOMEM);
 
@@ -942,19 +943,22 @@ static void bio_copy_kern_endio(struct bio *bio, int err)
 {
 	struct bio_vec *bvec;
 	const int read = bio_data_dir(bio) == READ;
-	char *p = bio->bi_private;
+	struct bio_map_data *bmd = bio->bi_private;
 	int i;
+	char *p = bmd->sgvecs[0].iov_base;
 
 	__bio_for_each_segment(bvec, bio, i, 0) {
 		char *addr = page_address(bvec->bv_page);
+		int len = bmd->iovecs[i].bv_len;
 
 		if (read && !err)
-			memcpy(p, addr, bvec->bv_len);
+			memcpy(p, addr, len);
 
 		__free_page(bvec->bv_page);
-		p += bvec->bv_len;
+		p += len;
 	}
 
+	bio_free_map_data(bmd);
 	bio_put(bio);
 }
 
@@ -978,11 +982,21 @@ struct bio *bio_copy_kern(struct request_queue *q, void *data, unsigned int len,
 	const int nr_pages = end - start;
 	struct bio *bio;
 	struct bio_vec *bvec;
+	struct bio_map_data *bmd;
 	int i, ret;
+	struct sg_iovec iov;
+
+	iov.iov_base = data;
+	iov.iov_len = len;
+
+	bmd = bio_alloc_map_data(nr_pages, 1, gfp_mask);
+	if (!bmd)
+		return ERR_PTR(-ENOMEM);
 
+	ret = -ENOMEM;
 	bio = bio_alloc(gfp_mask, nr_pages);
 	if (!bio)
-		return ERR_PTR(-ENOMEM);
+		goto out_bmd;
 
 	while (len) {
 		struct page *page;
@@ -1016,14 +1030,18 @@ struct bio *bio_copy_kern(struct request_queue *q, void *data, unsigned int len,
 		}
 	}
 
-	bio->bi_private = data;
+	bio->bi_private = bmd;
 	bio->bi_end_io = bio_copy_kern_endio;
+
+	bio_set_map_data(bmd, bio, &iov, 1);
 	return bio;
 cleanup:
 	bio_for_each_segment(bvec, bio, i)
 		__free_page(bvec->bv_page);
 
 	bio_put(bio);
+out_bmd:
+	bio_free_map_data(bmd);
 
 	return ERR_PTR(ret);
 }


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-9/kernel.spec,v
retrieving revision 1.749
retrieving revision 1.750
diff -u -r1.749 -r1.750
--- kernel.spec	30 Aug 2008 22:37:58 -0000	1.749
+++ kernel.spec	31 Aug 2008 01:22:56 -0000	1.750
@@ -607,6 +607,9 @@
 Patch400: linux-2.6-scsi-cpqarray-set-master.patch
 Patch402: linux-2.6-scsi-mpt-vmware-fix.patch
 
+Patch410: linux-2.6-bio-fix-__bio_copy_iov-handling-of-bv_len.patch
+Patch411: linux-2.6-bio-fix-bio_copy_kern-handling-of-bv_len.patch
+
 # filesystem patches
 Patch421: linux-2.6-squashfs.patch
 
@@ -1106,6 +1109,11 @@
 # ALSA
 #
 
+# block/bio
+#
+ApplyPatch linux-2.6-bio-fix-__bio_copy_iov-handling-of-bv_len.patch
+ApplyPatch linux-2.6-bio-fix-bio_copy_kern-handling-of-bv_len.patch
+
 # Filesystem patches.
 # cifs
 # Squashfs
@@ -1794,6 +1802,9 @@
 %kernel_variant_files -a /%{image_install_path}/xen*-%{KVERREL}.xen -e /etc/ld.so.conf.d/kernelcap-%{KVERREL}.xen.conf %{with_xen} xen
 
 %changelog
+* Sat Aug 30 2008 Chuck Ebbert <cebbert at redhat.com> 2.6.26.3-23
+- Add two bio patches scheduled for -stable.
+
 * Sat Aug 30 2008 Chuck Ebbert <cebbert at redhat.com> 2.6.26.3-22
 - specfile: don't use the latest stable update as the vanilla directory.
 




More information about the fedora-extras-commits mailing list