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? */