[patch 16/44] rd convert to new aops

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxxxx>
Signed-off-by: Nick Piggin <npiggin@xxxxxxx>

 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux