r1301 - in trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian: . patches

Christoph Hellwig hch-guest@haydn.debian.org
Wed, 25 Aug 2004 04:00:49 -0600


Author: hch-guest
Date: 2004-08-25 04:00:29 -0600 (Wed, 25 Aug 2004)
New Revision: 1301

Added:
   trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/bio_uncopy_user-memleak-2.dpatch
Modified:
   trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/changelog
   trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/00list-3
Log:

  * Update bio_uncopy_user-memleak to really fix the problem
    (closes: #267464) (Christoph Hellwig).



Modified: trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/changelog
===================================================================
--- trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/changelog	2004-08-25 09:43:51 UTC (rev 1300)
+++ trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/changelog	2004-08-25 10:00:29 UTC (rev 1301)
@@ -26,6 +26,9 @@
   * Add a comment about the Adaptec firmware rebuild situation to
     README.Debian (closes: #256757) (Christoph Hellwig).
 
+  * Update bio_uncopy_user-memleak to really fix the problem
+    (closes: #267464) (Christoph Hellwig).
+
  -- Andres Salomon <dilinger@voxel.net>  Wed, 18 Aug 2004 02:13:56 -0400
 
 kernel-source-2.6.8 (2.6.8-2) unstable; urgency=high

Modified: trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/00list-3
===================================================================
--- trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/00list-3	2004-08-25 09:43:51 UTC (rev 1300)
+++ trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/00list-3	2004-08-25 10:00:29 UTC (rev 1301)
@@ -31,7 +31,7 @@
 ia64-generic-no-smp-1-to-2
 ia64_cyclone_nosmp
 fix-sn_console-for-config_smp
-bio_uncopy_user-memleak
+bio_uncopy_user-memleak-2
 scsi-blacklist
 acpi-osname
 acpi-early

Added: trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/bio_uncopy_user-memleak-2.dpatch
===================================================================
--- trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/bio_uncopy_user-memleak-2.dpatch	2004-08-25 09:43:51 UTC (rev 1300)
+++ trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/bio_uncopy_user-memleak-2.dpatch	2004-08-25 10:00:29 UTC (rev 1301)
@@ -0,0 +1,95 @@
+#! /bin/sh -e 
+## <PATCHNAME>.dpatch by <PATCH_AUTHOR@EMAI>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Description: Fix big memory leak in bio_uncopy_user (SG_IO)
+## DP: Patch author: Kurt Garloff <garloff@suse.de>
+## DP: Upstream status: backport
+
+. $(dirname $0)/DPATCH
+
+@DPATCH@
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+#   2004/08/24 11:42:34-07:00 garloff@suse.de 
+#   [PATCH] fix bio_uncopy_user() mem leak
+#   
+#     When using bounce buffers for SG_IO commands with unaligned buffers in
+#     blk_rq_map_user(), we should free the pages from blk_rq_unmap_user() which
+#     calls bio_uncopy_user() for the non-BIO_USER_MAPPED case.  That function
+#     failed to free the pages for write requests.
+#   
+#     So we leaked pages and you machine would go OOM.  Rebooting helped ;-)
+#   
+#     This bug was triggered by writing audio CDs (but not on data CDs), as the
+#     audio frames are not aligned well (2352 bytes), so the user pages don't just
+#     get mapped.
+#   
+#     Bug was reported by Mathias Homan and debugged by Chris Mason + me.  (Jens
+#     is away.)
+#   
+#   From: Chris Mason <mason@suse.com>
+#   
+#     Fix the leak for real
+#   
+#   Signed-off-by: Kurt Garloff <garloff@suse.de>
+#   
+#   Signed-off-by: Andrew Morton <akpm@osdl.org>
+#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
+# 
+# fs/bio.c
+#   2004/08/24 02:09:01-07:00 garloff@suse.de +11 -12
+#   fix bio_uncopy_user() mem leak
+# 
+diff -Nru a/fs/bio.c b/fs/bio.c
+--- a/fs/bio.c	2004-08-25 11:58:23 +02:00
++++ b/fs/bio.c	2004-08-25 11:58:23 +02:00
+@@ -388,20 +388,17 @@
+ 	struct bio_vec *bvec;
+ 	int i, ret = 0;
+ 
+-	if (bio_data_dir(bio) == READ) {
+-		char *uaddr = bio->bi_private;
++	char *uaddr = bio->bi_private;
+ 
+-		__bio_for_each_segment(bvec, bio, i, 0) {
+-			char *addr = page_address(bvec->bv_page);
+-
+-			if (!ret && copy_to_user(uaddr, addr, bvec->bv_len))
+-				ret = -EFAULT;
++	__bio_for_each_segment(bvec, bio, i, 0) {
++		char *addr = page_address(bvec->bv_page);
++		if (bio_data_dir(bio) == READ && !ret &&
++		    copy_to_user(uaddr, addr, bvec->bv_len))
++			ret = -EFAULT;
+ 
+-			__free_page(bvec->bv_page);
+-			uaddr += bvec->bv_len;
+-		}
++		__free_page(bvec->bv_page);
++		uaddr += bvec->bv_len;
+ 	}
+-
+ 	bio_put(bio);
+ 	return ret;
+ }
+@@ -457,6 +454,7 @@
+ 	 */
+ 	if (!ret) {
+ 		if (!write_to_vm) {
++			unsigned long p = uaddr;
+ 			bio->bi_rw |= (1 << BIO_RW);
+ 			/*
+ 	 		 * for a write, copy in data to kernel pages
+@@ -465,8 +463,9 @@
+ 			bio_for_each_segment(bvec, bio, i) {
+ 				char *addr = page_address(bvec->bv_page);
+ 
+-				if (copy_from_user(addr, (char *) uaddr, bvec->bv_len))
++				if (copy_from_user(addr, (char *) p, bvec->bv_len))
+ 					goto cleanup;
++				p += bvec->bv_len;
+ 			}
+ 		}
+