There are a series of open coded reimplementation of memclear_highpage_flush
all over the page cache code. Call memclear_highpage_flush in those locations.
Consolidates code and eases maintenance.

[There seems to be a better patch in mm. This patch here is just to make things
work against 2.6.21 until the rest of the patch is diffed against mm]

Signed-off-by: Christoph Lameter <[EMAIL PROTECTED]>

---
 fs/buffer.c      |   77 ++++++++++++-------------------------------------------
 fs/direct-io.c   |    8 +----
 fs/libfs.c       |   10 +++----
 fs/mpage.c       |   12 ++------
 mm/filemap_xip.c |    6 ----
 5 files changed, 29 insertions(+), 84 deletions(-)

Index: linux-2.6.21-rc7/fs/buffer.c
===================================================================
--- linux-2.6.21-rc7.orig/fs/buffer.c   2007-04-23 14:19:04.000000000 -0700
+++ linux-2.6.21-rc7/fs/buffer.c        2007-04-23 14:44:09.000000000 -0700
@@ -1803,17 +1803,12 @@ static int __block_prepare_write(struct 
                                        continue;
                                }
                                if (block_end > to || block_start < from) {
-                                       void *kaddr;
-
-                                       kaddr = kmap_atomic(page, KM_USER0);
                                        if (block_end > to)
-                                               memset(kaddr+to, 0,
-                                                       block_end-to);
+                                               memclear_highpage_flush(page,
+                                                       to, block_end - to);
                                        if (block_start < from)
-                                               memset(kaddr+block_start,
-                                                       0, from-block_start);
-                                       flush_dcache_page(page);
-                                       kunmap_atomic(kaddr, KM_USER0);
+                                               memclear_highpage_flush(page,
+                                               block_start, from - 
block_start);
                                }
                                continue;
                        }
@@ -1861,13 +1856,8 @@ static int __block_prepare_write(struct 
                if (block_start >= to)
                        break;
                if (buffer_new(bh)) {
-                       void *kaddr;
-
                        clear_buffer_new(bh);
-                       kaddr = kmap_atomic(page, KM_USER0);
-                       memset(kaddr+block_start, 0, bh->b_size);
-                       flush_dcache_page(page);
-                       kunmap_atomic(kaddr, KM_USER0);
+                       memclear_highpage_flush(page, block_start, bh->b_size);
                        set_buffer_uptodate(bh);
                        mark_buffer_dirty(bh);
                }
@@ -1955,10 +1945,7 @@ int block_read_full_page(struct page *pa
                                        SetPageError(page);
                        }
                        if (!buffer_mapped(bh)) {
-                               void *kaddr = kmap_atomic(page, KM_USER0);
-                               memset(kaddr + i * blocksize, 0, blocksize);
-                               flush_dcache_page(page);
-                               kunmap_atomic(kaddr, KM_USER0);
+                               memclear_highpage_flush(page, i * blocksize, 
blocksize);
                                if (!err)
                                        set_buffer_uptodate(bh);
                                continue;
@@ -2101,7 +2088,6 @@ int cont_prepare_write(struct page *page
        long status;
        unsigned zerofrom;
        unsigned blocksize = 1 << inode->i_blkbits;
-       void *kaddr;
 
        while(page->index > (pgpos = *bytes>>PAGE_CACHE_SHIFT)) {
                status = -ENOMEM;
@@ -2123,10 +2109,8 @@ int cont_prepare_write(struct page *page
                                                PAGE_CACHE_SIZE, get_block);
                if (status)
                        goto out_unmap;
-               kaddr = kmap_atomic(new_page, KM_USER0);
-               memset(kaddr+zerofrom, 0, PAGE_CACHE_SIZE-zerofrom);
-               flush_dcache_page(new_page);
-               kunmap_atomic(kaddr, KM_USER0);
+               memclear_highpage_flush(new_page, zerofrom,
+                                       PAGE_CACHE_SIZE - zerofrom);
                generic_commit_write(NULL, new_page, zerofrom, PAGE_CACHE_SIZE);
                unlock_page(new_page);
                page_cache_release(new_page);
@@ -2153,10 +2137,7 @@ int cont_prepare_write(struct page *page
        if (status)
                goto out1;
        if (zerofrom < offset) {
-               kaddr = kmap_atomic(page, KM_USER0);
-               memset(kaddr+zerofrom, 0, offset-zerofrom);
-               flush_dcache_page(page);
-               kunmap_atomic(kaddr, KM_USER0);
+               memclear_highpage_flush(page, zerofrom, offset - zerofrom);
                __block_commit_write(inode, page, zerofrom, offset);
        }
        return 0;
@@ -2243,7 +2224,6 @@ int nobh_prepare_write(struct page *page
        unsigned block_in_page;
        unsigned block_start;
        sector_t block_in_file;
-       char *kaddr;
        int nr_reads = 0;
        int i;
        int ret = 0;
@@ -2283,13 +2263,12 @@ int nobh_prepare_write(struct page *page
                if (PageUptodate(page))
                        continue;
                if (buffer_new(&map_bh) || !buffer_mapped(&map_bh)) {
-                       kaddr = kmap_atomic(page, KM_USER0);
                        if (block_start < from)
-                               memset(kaddr+block_start, 0, from-block_start);
+                               memclear_highpage_flush(page,
+                                       block_start, from - block_start);
                        if (block_end > to)
-                               memset(kaddr + to, 0, block_end - to);
-                       flush_dcache_page(page);
-                       kunmap_atomic(kaddr, KM_USER0);
+                               memclear_highpage_flush(page,
+                                       to, block_end - to);
                        continue;
                }
                if (buffer_uptodate(&map_bh))
@@ -2355,10 +2334,7 @@ failed:
         * Error recovery is pretty slack.  Clear the page and mark it dirty
         * so we'll later zero out any blocks which _were_ allocated.
         */
-       kaddr = kmap_atomic(page, KM_USER0);
-       memset(kaddr, 0, PAGE_CACHE_SIZE);
-       flush_dcache_page(page);
-       kunmap_atomic(kaddr, KM_USER0);
+       memclear_highpage_flush(page, 0, PAGE_SIZE);
        SetPageUptodate(page);
        set_page_dirty(page);
        return ret;
@@ -2397,7 +2373,6 @@ int nobh_writepage(struct page *page, ge
        loff_t i_size = i_size_read(inode);
        const pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
        unsigned offset;
-       void *kaddr;
        int ret;
 
        /* Is the page fully inside i_size? */
@@ -2428,10 +2403,7 @@ int nobh_writepage(struct page *page, ge
         * the  page size, the remaining memory is zeroed when mapped, and
         * writes to that region are not written out to the file."
         */
-       kaddr = kmap_atomic(page, KM_USER0);
-       memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset);
-       flush_dcache_page(page);
-       kunmap_atomic(kaddr, KM_USER0);
+       memclear_highpage_flush(page, offset, PAGE_CACHE_SIZE - offset);
 out:
        ret = mpage_writepage(page, get_block, wbc);
        if (ret == -EAGAIN)
@@ -2452,7 +2424,6 @@ int nobh_truncate_page(struct address_sp
        unsigned to;
        struct page *page;
        const struct address_space_operations *a_ops = mapping->a_ops;
-       char *kaddr;
        int ret = 0;
 
        if ((offset & (blocksize - 1)) == 0)
@@ -2466,10 +2437,7 @@ int nobh_truncate_page(struct address_sp
        to = (offset + blocksize) & ~(blocksize - 1);
        ret = a_ops->prepare_write(NULL, page, offset, to);
        if (ret == 0) {
-               kaddr = kmap_atomic(page, KM_USER0);
-               memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset);
-               flush_dcache_page(page);
-               kunmap_atomic(kaddr, KM_USER0);
+               memclear_highpage_flush(page, offset, PAGE_CACHE_SIZE - offset);
                /*
                 * It would be more correct to call aops->commit_write()
                 * here, but this is more efficient.
@@ -2495,7 +2463,6 @@ int block_truncate_page(struct address_s
        struct inode *inode = mapping->host;
        struct page *page;
        struct buffer_head *bh;
-       void *kaddr;
        int err;
 
        blocksize = 1 << inode->i_blkbits;
@@ -2549,11 +2516,7 @@ int block_truncate_page(struct address_s
                        goto unlock;
        }
 
-       kaddr = kmap_atomic(page, KM_USER0);
-       memset(kaddr + offset, 0, length);
-       flush_dcache_page(page);
-       kunmap_atomic(kaddr, KM_USER0);
-
+       memclear_highpage_flush(page, offset, length);
        mark_buffer_dirty(bh);
        err = 0;
 
@@ -2574,7 +2537,6 @@ int block_write_full_page(struct page *p
        loff_t i_size = i_size_read(inode);
        const pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
        unsigned offset;
-       void *kaddr;
 
        /* Is the page fully inside i_size? */
        if (page->index < end_index)
@@ -2600,10 +2562,7 @@ int block_write_full_page(struct page *p
         * the  page size, the remaining memory is zeroed when mapped, and
         * writes to that region are not written out to the file."
         */
-       kaddr = kmap_atomic(page, KM_USER0);
-       memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset);
-       flush_dcache_page(page);
-       kunmap_atomic(kaddr, KM_USER0);
+       memclear_highpage_flush(page, offset, PAGE_CACHE_SIZE - offset);
        return __block_write_full_page(inode, page, get_block, wbc);
 }
 
Index: linux-2.6.21-rc7/fs/direct-io.c
===================================================================
--- linux-2.6.21-rc7.orig/fs/direct-io.c        2007-04-23 14:28:35.000000000 
-0700
+++ linux-2.6.21-rc7/fs/direct-io.c     2007-04-23 14:29:21.000000000 -0700
@@ -867,7 +867,6 @@ static int do_direct_IO(struct dio *dio)
 do_holes:
                        /* Handle holes */
                        if (!buffer_mapped(map_bh)) {
-                               char *kaddr;
                                loff_t i_size_aligned;
 
                                /* AKPM: eargh, -ENOTBLK is a hack */
@@ -888,11 +887,8 @@ do_holes:
                                        page_cache_release(page);
                                        goto out;
                                }
-                               kaddr = kmap_atomic(page, KM_USER0);
-                               memset(kaddr + (block_in_page << blkbits),
-                                               0, 1 << blkbits);
-                               flush_dcache_page(page);
-                               kunmap_atomic(kaddr, KM_USER0);
+                               memclear_highpage_flush(page,
+                                       block_in_page << blkbits, 1 << blkbits);
                                dio->block_in_file++;
                                block_in_page++;
                                goto next_block;
Index: linux-2.6.21-rc7/fs/libfs.c
===================================================================
--- linux-2.6.21-rc7.orig/fs/libfs.c    2007-04-23 14:29:49.000000000 -0700
+++ linux-2.6.21-rc7/fs/libfs.c 2007-04-23 14:32:19.000000000 -0700
@@ -332,11 +332,11 @@ int simple_prepare_write(struct file *fi
 {
        if (!PageUptodate(page)) {
                if (to - from != PAGE_CACHE_SIZE) {
-                       void *kaddr = kmap_atomic(page, KM_USER0);
-                       memset(kaddr, 0, from);
-                       memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
-                       flush_dcache_page(page);
-                       kunmap_atomic(kaddr, KM_USER0);
+                       if (from)
+                               memclear_highpage_flush(page, 0, from);
+                       if (to < PAGE_CACHE_SIZE)
+                               memclear_highpage_flush(page, to,
+                                       PAGE_CACHE_SIZE - to);
                }
        }
        return 0;
Index: linux-2.6.21-rc7/fs/mpage.c
===================================================================
--- linux-2.6.21-rc7.orig/fs/mpage.c    2007-04-23 14:32:27.000000000 -0700
+++ linux-2.6.21-rc7/fs/mpage.c 2007-04-23 14:53:55.000000000 -0700
@@ -284,11 +284,8 @@ do_mpage_readpage(struct bio *bio, struc
        }
 
        if (first_hole != blocks_per_page) {
-               char *kaddr = kmap_atomic(page, KM_USER0);
-               memset(kaddr + (first_hole << blkbits), 0,
+               memclear_highpage_flush(page, first_hole << blkbits,
                                PAGE_CACHE_SIZE - (first_hole << blkbits));
-               flush_dcache_page(page);
-               kunmap_atomic(kaddr, KM_USER0);
                if (first_hole == 0) {
                        SetPageUptodate(page);
                        unlock_page(page);
@@ -576,14 +573,11 @@ page_is_mapped:
                 * written out to the file."
                 */
                unsigned offset = i_size & (PAGE_CACHE_SIZE - 1);
-               char *kaddr;
 
                if (page->index > end_index || !offset)
                        goto confused;
-               kaddr = kmap_atomic(page, KM_USER0);
-               memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset);
-               flush_dcache_page(page);
-               kunmap_atomic(kaddr, KM_USER0);
+               memclear_highpage_flush(page, offset,
+                       PAGE_CACHE_SIZE - offset);
        }
 
        /*
Index: linux-2.6.21-rc7/mm/filemap_xip.c
===================================================================
--- linux-2.6.21-rc7.orig/mm/filemap_xip.c      2007-04-23 14:34:41.000000000 
-0700
+++ linux-2.6.21-rc7/mm/filemap_xip.c   2007-04-23 14:35:26.000000000 -0700
@@ -458,11 +458,7 @@ xip_truncate_page(struct address_space *
                else
                        return PTR_ERR(page);
        }
-       kaddr = kmap_atomic(page, KM_USER0);
-       memset(kaddr + offset, 0, length);
-       kunmap_atomic(kaddr, KM_USER0);
-
-       flush_dcache_page(page);
+       memclear_highpage_flush(page, offset, length);
        return 0;
 }
 EXPORT_SYMBOL_GPL(xip_truncate_page);

--
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to