Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 1343

kernel-2.6.18-238.el5.src.rpm

From: Steven Whitehouse <swhiteho@redhat.com>
Subject: [RHEL 5.1] [GFS2] bz #236087, GFS2: mmap problems with distributed 	test cases
Date: Thu, 10 May 2007 11:37:43 +0100
Bugzilla: 236087
Message-Id: <1178793463.7476.39.camel@quoit>
Changelog: [GFS2] mmap problems with distributed test cases


Hi,

The following patch is a combination of two upstream patches. Both
patches are in Linus' kernel tree, one has been there for a number of
months. The patch has been tested and passes the QE mmap quick tests.

In addition to the reported problem in the bug, this also adds some
missing flush_dcache_page() calls and also fixes a bug in
gfs2_releasepage() which was fixed in one of the two upstream patches.

The two upstream patches are:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=61057c6bb3a3d14cf2bea6ca20dc6d367e1d852e
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=bf126aee6d54fe1e509846abf3b27aba84c6d7ce


Steve.


--------------------------------------------------------------------------

--- linux-rhel-base/fs/gfs2/ops_address.c	2007-05-10 11:13:49.000000000 +0100
+++ linux-2.6.18.noarch/fs/gfs2/ops_address.c	2007-05-10 11:17:30.000000000 +0100
@@ -156,19 +156,6 @@
 	return 0;
 }
 
-static int zero_readpage(struct page *page)
-{
-	void *kaddr;
-
-	kaddr = kmap_atomic(page, KM_USER0);
-	memset(kaddr, 0, PAGE_CACHE_SIZE);
-	kunmap_atomic(kaddr, KM_USER0);
-
-	SetPageUptodate(page);
-
-	return 0;
-}
-
 /**
  * stuffed_readpage - Fill in a Linux page with stuffed file data
  * @ip: the inode
@@ -183,9 +170,19 @@
 	void *kaddr;
 	int error;
 
-	/* Only the first page of a stuffed file might contain data */
-	if (unlikely(page->index))
-		return zero_readpage(page);
+	/*
+	 * Due to the order of unstuffing files and ->nopage(), we can be
+	 * asked for a zero page in the case of a stuffed file being extended,
+	 * so we need to supply one here. It doesn't happen often.
+	 */
+	if (unlikely(page->index)) {
+		kaddr = kmap_atomic(page, KM_USER0);
+		memset(kaddr, 0, PAGE_CACHE_SIZE);
+		kunmap_atomic(kaddr, KM_USER0);
+		flush_dcache_page(page);
+		SetPageUptodate(page);
+		return 0;
+	}
 
 	error = gfs2_meta_inode_buffer(ip, &dibh);
 	if (error)
@@ -196,9 +193,8 @@
 	       ip->i_di.di_size);
 	memset(kaddr + ip->i_di.di_size, 0, PAGE_CACHE_SIZE - ip->i_di.di_size);
 	kunmap_atomic(kaddr, KM_USER0);
-
+	flush_dcache_page(page);
 	brelse(dibh);
-
 	SetPageUptodate(page);
 
 	return 0;
@@ -755,6 +751,9 @@
 			if (!atomic_read(&aspace->i_writecount))
 				return 0;
 
+			if (!(gfp_mask & __GFP_WAIT))
+				return 0;
+
 			if (time_after_eq(jiffies, t)) {
 				stuck_releasepage(bh);
 				/* should we withdraw here? */