Also clean up various little things.

I've got rid of the comment from akpm, because now that make_page_uptodate
is only called from 2 places, it is pretty easy to see that the buffers
are in an uptodate state at the time of the call. Actually, it was OK before
my patch as well, because the memset is equivalent to reading from disk
of course... however it is more explicit where the updates come from now.

Cc: Linux Filesystems <linux-fsdevel@vger.kernel.org>
Signed-off-by: Nick Piggin <[EMAIL PROTECTED]>

 drivers/block/rd.c |  125 ++++++++++++++++++++++++++++++-----------------------
 1 file changed, 73 insertions(+), 52 deletions(-)

Index: linux-2.6/drivers/block/rd.c
===================================================================
--- linux-2.6.orig/drivers/block/rd.c
+++ linux-2.6/drivers/block/rd.c
@@ -104,50 +104,60 @@ static void make_page_uptodate(struct pa
                struct buffer_head *head = bh;
 
                do {
-                       if (!buffer_uptodate(bh)) {
-                               memset(bh->b_data, 0, bh->b_size);
-                               /*
-                                * akpm: I'm totally undecided about this.  The
-                                * buffer has just been magically brought "up to
-                                * date", but nobody should want to be reading
-                                * it anyway, because it hasn't been used for
-                                * anything yet.  It is still in a "not read
-                                * from disk yet" state.
-                                *
-                                * But non-uptodate buffers against an uptodate
-                                * page are against the rules.  So do it anyway.
-                                */
+                       if (!buffer_uptodate(bh))
                                 set_buffer_uptodate(bh);
-                       }
                } while ((bh = bh->b_this_page) != head);
-       } else {
-               memset(page_address(page), 0, PAGE_CACHE_SIZE);
        }
-       flush_dcache_page(page);
        SetPageUptodate(page);
 }
 
 static int ramdisk_readpage(struct file *file, struct page *page)
 {
-       if (!PageUptodate(page))
+       if (!PageUptodate(page)) {
+               memclear_highpage_flush(page, 0, PAGE_CACHE_SIZE);
                make_page_uptodate(page);
+       }
        unlock_page(page);
        return 0;
 }
 
-static int ramdisk_prepare_write(struct file *file, struct page *page,
-                               unsigned offset, unsigned to)
-{
-       if (!PageUptodate(page))
-               make_page_uptodate(page);
+static int ramdisk_write_begin(struct file *file, struct address_space 
*mapping,
+                       loff_t pos, unsigned len, unsigned flags,
+                       struct page **pagep, void **fsdata)
+{
+       struct page *page;
+       pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+
+       page = __grab_cache_page(mapping, index);
+       if (!page)
+               return -ENOMEM;
+       *pagep = page;
        return 0;
 }
 
-static int ramdisk_commit_write(struct file *file, struct page *page,
-                               unsigned offset, unsigned to)
-{
+static int ramdisk_write_end(struct file *file, struct address_space *mapping,
+                       loff_t pos, unsigned len, unsigned copied,
+                       struct page *page, void *fsdata)
+{
+       if (!PageUptodate(page)) {
+               if (copied != PAGE_CACHE_SIZE) {
+                       void *dst;
+                       unsigned from = pos & (PAGE_CACHE_SIZE - 1);
+                       unsigned to = from + copied;
+
+                       dst = kmap_atomic(page, KM_USER0);
+                       memset(dst, 0, from);
+                       memset(dst + to, 0, PAGE_CACHE_SIZE - to);
+                       flush_dcache_page(page);
+                       kunmap_atomic(dst, KM_USER0);
+               }
+               make_page_uptodate(page);
+       }
+
        set_page_dirty(page);
-       return 0;
+       unlock_page(page);
+       page_cache_release(page);
+       return copied;
 }
 
 /*
@@ -191,8 +201,8 @@ static int ramdisk_set_page_dirty(struct
 
 static const struct address_space_operations ramdisk_aops = {
        .readpage       = ramdisk_readpage,
-       .prepare_write  = ramdisk_prepare_write,
-       .commit_write   = ramdisk_commit_write,
+       .write_begin    = ramdisk_write_begin,
+       .write_end      = ramdisk_write_end,
        .writepage      = ramdisk_writepage,
        .set_page_dirty = ramdisk_set_page_dirty,
        .writepages     = ramdisk_writepages,
@@ -201,13 +211,14 @@ static const struct address_space_operat
 static int rd_blkdev_pagecache_IO(int rw, struct bio_vec *vec, sector_t sector,
                                struct address_space *mapping)
 {
-       pgoff_t index = sector >> (PAGE_CACHE_SHIFT - 9);
+       loff_t pos = sector << 9;
        unsigned int vec_offset = vec->bv_offset;
-       int offset = (sector << 9) & ~PAGE_CACHE_MASK;
        int size = vec->bv_len;
        int err = 0;
 
        do {
+               pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+               unsigned offset = pos & ~PAGE_CACHE_MASK;
                int count;
                struct page *page;
                char *src;
@@ -216,40 +227,50 @@ static int rd_blkdev_pagecache_IO(int rw
                count = PAGE_CACHE_SIZE - offset;
                if (count > size)
                        count = size;
-               size -= count;
-
-               page = grab_cache_page(mapping, index);
-               if (!page) {
-                       err = -ENOMEM;
-                       goto out;
-               }
 
-               if (!PageUptodate(page))
-                       make_page_uptodate(page);
+               if (rw == WRITE) {
+                       err = pagecache_write_begin(NULL, mapping, pos, count,
+                                                       0, &page, NULL);
+                       if (err)
+                               goto out;
 
-               index++;
+                       src = kmap_atomic(vec->bv_page, KM_USER0) + vec_offset;
+                       dst = kmap_atomic(page, KM_USER1) + offset;
+               } else {
+again:
+                       page = __grab_cache_page(mapping, index);
+                       if (!page) {
+                               err = -ENOMEM;
+                               goto out;
+                       }
+                       if (!PageUptodate(page)) {
+                               mapping->a_ops->readpage(NULL, page);
+                               goto again;
+                       }
 
-               if (rw == READ) {
                        src = kmap_atomic(page, KM_USER0) + offset;
                        dst = kmap_atomic(vec->bv_page, KM_USER1) + vec_offset;
-               } else {
-                       src = kmap_atomic(vec->bv_page, KM_USER0) + vec_offset;
-                       dst = kmap_atomic(page, KM_USER1) + offset;
                }
-               offset = 0;
-               vec_offset += count;
+
 
                memcpy(dst, src, count);
 
                kunmap_atomic(src, KM_USER0);
                kunmap_atomic(dst, KM_USER1);
 
-               if (rw == READ)
+               if (rw == READ) {
                        flush_dcache_page(vec->bv_page);
-               else
-                       set_page_dirty(page);
-               unlock_page(page);
-               put_page(page);
+                       unlock_page(page);
+                       page_cache_release(page);
+               } else {
+                       flush_dcache_page(page);
+                       pagecache_write_end(NULL, mapping, pos, count,
+                                                       count, page, NULL);
+               }
+
+               pos += count;
+               vec_offset += count;
+               size -= count;
        } while (size);
 
  out:

-- 

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

Reply via email to