linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Badari Pulavarty <pbadari@us.ibm.com>
To: Andrew Morton <akpm@osdl.org>
Cc: linux-fsdevel@vger.kernel.org,
	ext2-devel <ext2-devel@lists.sourceforge.net>
Subject: [RFC] [PATCH] Generic mpage_writepage() support
Date: 15 Feb 2005 16:02:21 -0800	[thread overview]
Message-ID: <1108512141.20053.1490.camel@dyn318077bld.beaverton.ibm.com> (raw)
In-Reply-To: <20050215095443.3e646401.akpm@osdl.org>

[-- Attachment #1: Type: text/plain, Size: 825 bytes --]

On Tue, 2005-02-15 at 09:54, Andrew Morton wrote:
> Badari Pulavarty <pbadari@us.ibm.com> wrote:
> >
> > Yep. nobh_prepare_write() doesn't add any bufferheads. But
> >  we call block_write_full_page() even for "nobh" case, which 
> >  does create bufferheads, attaches to the page and operates
> >  on them..
> 
> hmm, yeah, OK, we'll attach bh's in that case.  It's a rare case though -
> when a dirty page falls off the end of the LRU.  There's no particular
> reason why we cannot have a real mpage_writepage() which doesn't use bh's
> and employ that.
> 
> I coulda sworn we used to have one.

Hi Andrew,

Here is my first version of mpage_writepage() patch.
I haven't handle the "confused" case yet - I need to
pass a function pointer to handle it. Just for
initial code review. I am still testing it.

Thanks,
Badari



[-- Attachment #2: mpage-writepage.patch --]
[-- Type: text/x-patch, Size: 4263 bytes --]

diff -Narup -X dontdiff linux-2.6.10/fs/ext2/inode.c linux-2.6.10.nobh/fs/ext2/inode.c
--- linux-2.6.10/fs/ext2/inode.c	2004-12-24 13:33:51.000000000 -0800
+++ linux-2.6.10.nobh/fs/ext2/inode.c	2005-02-15 16:17:56.000000000 -0800
@@ -626,6 +626,12 @@ ext2_nobh_prepare_write(struct file *fil
 	return nobh_prepare_write(page,from,to,ext2_get_block);
 }
 
+static int ext2_nobh_writepage(struct page *page, 
+			struct writeback_control *wbc)
+{
+	return mpage_writepage(page, ext2_get_block, wbc);
+}
+
 static sector_t ext2_bmap(struct address_space *mapping, sector_t block)
 {
 	return generic_block_bmap(mapping,block,ext2_get_block);
@@ -675,7 +681,7 @@ struct address_space_operations ext2_aop
 struct address_space_operations ext2_nobh_aops = {
 	.readpage		= ext2_readpage,
 	.readpages		= ext2_readpages,
-	.writepage		= ext2_writepage,
+	.writepage		= ext2_nobh_writepage,
 	.sync_page		= block_sync_page,
 	.prepare_write		= ext2_nobh_prepare_write,
 	.commit_write		= nobh_commit_write,
diff -Narup -X dontdiff linux-2.6.10/fs/jfs/inode.c linux-2.6.10.nobh/fs/jfs/inode.c
--- linux-2.6.10/fs/jfs/inode.c	2004-12-24 13:33:48.000000000 -0800
+++ linux-2.6.10.nobh/fs/jfs/inode.c	2005-02-15 16:48:32.022885240 -0800
@@ -281,7 +281,7 @@ static int jfs_get_block(struct inode *i
 
 static int jfs_writepage(struct page *page, struct writeback_control *wbc)
 {
-	return block_write_full_page(page, jfs_get_block, wbc);
+	return mpage_writepage(page, jfs_get_block, wbc);
 }
 
 static int jfs_writepages(struct address_space *mapping,
diff -Narup -X dontdiff linux-2.6.10/fs/mpage.c linux-2.6.10.nobh/fs/mpage.c
--- linux-2.6.10/fs/mpage.c	2004-12-24 13:34:26.000000000 -0800
+++ linux-2.6.10.nobh/fs/mpage.c	2005-02-15 16:19:20.000000000 -0800
@@ -386,7 +386,7 @@ EXPORT_SYMBOL(mpage_readpage);
  * just allocate full-size (16-page) BIOs.
  */
 static struct bio *
-mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block,
+__mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block,
 	sector_t *last_block_in_bio, int *ret, struct writeback_control *wbc)
 {
 	struct address_space *mapping = page->mapping;
@@ -706,7 +706,7 @@ retry:
 							&mapping->flags);
 				}
 			} else {
-				bio = mpage_writepage(bio, page, get_block,
+				bio = __mpage_writepage(bio, page, get_block,
 						&last_block_in_bio, &ret, wbc);
 			}
 			if (ret || (--(wbc->nr_to_write) <= 0))
@@ -734,4 +734,59 @@ retry:
 		mpage_bio_submit(WRITE, bio);
 	return ret;
 }
+
+/*
+ * The generic ->writepage function for address_spaces
+ */
+int mpage_writepage(struct page *page, get_block_t *get_block,
+			struct writeback_control *wbc)
+{
+	struct inode * const inode = page->mapping->host;
+	loff_t i_size = i_size_read(inode);
+	const pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
+	unsigned offset;
+	void *kaddr;
+	int ret = 0;
+	struct bio *bio = NULL;
+	sector_t last_block_in_bio = 0;
+
+	/* Is the page fully inside i_size? */
+	if (page->index < end_index) {
+		bio = __mpage_writepage(bio, page, get_block,
+				 &last_block_in_bio, &ret, wbc);
+		goto done;
+	}
+
+	/* Is the page fully outside i_size? (truncate in progress) */
+	offset = i_size & (PAGE_CACHE_SIZE-1);
+	if (page->index >= end_index+1 || !offset) {
+		/*
+		 * The page may have dirty, unmapped buffers.  For example,
+		 * they may have been added in ext3_writepage().  Make them
+		 * freeable here, so the page does not leak.
+		 */
+		block_invalidatepage(page, 0);
+		unlock_page(page);
+		return 0; /* don't care */
+	}
+
+	/*
+	 * The page straddles i_size.  It must be zeroed out on each and every
+	 * writepage invokation because it may be mmapped.  "A file is mapped
+	 * in multiples of the page size.  For a file that is not a multiple of
+	 * 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);
+	bio = __mpage_writepage(bio, page, get_block, 
+			&last_block_in_bio, &ret, wbc);
+done:
+	if (bio)
+		mpage_bio_submit(WRITE, bio);
+	return ret;
+}
 EXPORT_SYMBOL(mpage_writepages);
+EXPORT_SYMBOL(mpage_writepage);

  parent reply	other threads:[~2005-02-16  0:02 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-02-14 19:30 Bufferheads & page-cache reference Badari Pulavarty
2005-02-14 19:31 ` [Ext2-devel] " Sonny Rao
2005-02-14 21:40 ` Andrew Morton
2005-02-14 22:10   ` William Lee Irwin III
2005-02-14 22:31     ` Andrew Morton
2005-02-14 22:50       ` William Lee Irwin III
2005-02-15  0:22         ` Badari Pulavarty
2005-02-15  2:57           ` Andrew Morton
2005-02-15 16:03             ` Badari Pulavarty
2005-02-15 17:26               ` Andrew Morton
2005-02-15  1:27   ` Badari Pulavarty
2005-02-15  3:05     ` Andrew Morton
2005-02-15 16:46       ` Badari Pulavarty
2005-02-15 17:54         ` Andrew Morton
2005-02-15 18:15           ` Badari Pulavarty
2005-02-15 19:07           ` Nikita Danilov
2005-02-15 19:39             ` Badari Pulavarty
2005-02-15 20:00               ` Andrew Morton
2005-02-16  0:02           ` Badari Pulavarty [this message]
2005-02-16 11:41             ` [RFC] [PATCH] Generic mpage_writepage() support Nikita Danilov
2005-02-16 18:37               ` Badari Pulavarty
2005-02-16 19:09                 ` Dave Kleikamp
2005-02-16 19:28                   ` Badari Pulavarty
2005-02-16 19:43                     ` Dave Kleikamp
2005-02-16 21:38                       ` [Ext2-devel] " Badari Pulavarty
2005-02-16 21:46                         ` Dave Kleikamp
2005-02-17  0:13                           ` [RFC] [PATCH] nobh_write_page() support Badari Pulavarty

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1108512141.20053.1490.camel@dyn318077bld.beaverton.ibm.com \
    --to=pbadari@us.ibm.com \
    --cc=akpm@osdl.org \
    --cc=ext2-devel@lists.sourceforge.net \
    --cc=linux-fsdevel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).