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;
+ }
+ }
+