From: Christoph Hellwig <hch@lst.de>
To: viro@zeniv.linux.org.uk, npiggin@suse.de
Cc: jack@suse.cz, linux-fsdevel@vger.kernel.org
Subject: [PATCH 5/6] introduce __block_write_begin
Date: Sun, 30 May 2010 22:50:18 +0200 [thread overview]
Message-ID: <20100530205018.GF21002@lst.de> (raw)
In-Reply-To: <20100530204932.GA21002@lst.de>
Split up the block_write_begin implementation - __block_write_begin is a new
trivial wrapper for block_prepare_write that always takes an already
allocated page and can be either called from block_write_begin or filesystem
code that already has a page allocated. Remove the handling of already
allocated pages from block_write_begin after switching all callers that
do it to __block_write_begin.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: linux-2.6/fs/buffer.c
===================================================================
--- linux-2.6.orig/fs/buffer.c 2010-05-30 22:32:22.754253961 +0200
+++ linux-2.6/fs/buffer.c 2010-05-30 22:40:16.496254519 +0200
@@ -1833,9 +1833,10 @@ void page_zero_new_buffers(struct page *
}
EXPORT_SYMBOL(page_zero_new_buffers);
-static int __block_prepare_write(struct inode *inode, struct page *page,
- unsigned from, unsigned to, get_block_t *get_block)
+int block_prepare_write(struct page *page, unsigned from, unsigned to,
+ get_block_t *get_block)
{
+ struct inode *inode = page->mapping->host;
unsigned block_start, block_end;
sector_t block;
int err = 0;
@@ -1908,10 +1909,13 @@ static int __block_prepare_write(struct
if (!buffer_uptodate(*wait_bh))
err = -EIO;
}
- if (unlikely(err))
+ if (unlikely(err)) {
page_zero_new_buffers(page, from, to);
+ ClearPageUptodate(page);
+ }
return err;
}
+EXPORT_SYMBOL(block_prepare_write);
static int __block_commit_write(struct inode *inode, struct page *page,
unsigned from, unsigned to)
@@ -1948,6 +1952,14 @@ static int __block_commit_write(struct i
return 0;
}
+int __block_write_begin(struct page *page, loff_t pos, unsigned len,
+ get_block_t *get_block)
+{
+ unsigned start = pos & (PAGE_CACHE_SIZE - 1);
+
+ return block_prepare_write(page, start, start + len, get_block);
+}
+
/*
* Filesystems implementing the new truncate sequence should use the
* _newtrunc postfix variant which won't incorrectly call vmtruncate.
@@ -1958,41 +1970,22 @@ int block_write_begin_newtrunc(struct fi
struct page **pagep, void **fsdata,
get_block_t *get_block)
{
- struct inode *inode = mapping->host;
- int status = 0;
+ pgoff_t index = pos >> PAGE_CACHE_SHIFT;
struct page *page;
- pgoff_t index;
- unsigned start, end;
- int ownpage = 0;
+ int status;
- index = pos >> PAGE_CACHE_SHIFT;
- start = pos & (PAGE_CACHE_SIZE - 1);
- end = start + len;
-
- page = *pagep;
- if (page == NULL) {
- ownpage = 1;
- page = grab_cache_page_write_begin(mapping, index, flags);
- if (!page) {
- status = -ENOMEM;
- goto out;
- }
- *pagep = page;
- } else
- BUG_ON(!PageLocked(page));
+ page = grab_cache_page_write_begin(mapping, index, flags);
+ if (!page)
+ return -ENOMEM;
- status = __block_prepare_write(inode, page, start, end, get_block);
+ status = __block_write_begin(page, pos, len, get_block);
if (unlikely(status)) {
- ClearPageUptodate(page);
-
- if (ownpage) {
- unlock_page(page);
- page_cache_release(page);
- *pagep = NULL;
- }
+ unlock_page(page);
+ page_cache_release(page);
+ page = NULL;
}
-out:
+ *pagep = page;
return status;
}
EXPORT_SYMBOL(block_write_begin_newtrunc);
@@ -2379,17 +2372,6 @@ out:
}
EXPORT_SYMBOL(cont_write_begin);
-int block_prepare_write(struct page *page, unsigned from, unsigned to,
- get_block_t *get_block)
-{
- struct inode *inode = page->mapping->host;
- int err = __block_prepare_write(inode, page, from, to, get_block);
- if (err)
- ClearPageUptodate(page);
- return err;
-}
-EXPORT_SYMBOL(block_prepare_write);
-
int block_commit_write(struct page *page, unsigned from, unsigned to)
{
struct inode *inode = page->mapping->host;
Index: linux-2.6/fs/ext2/dir.c
===================================================================
--- linux-2.6.orig/fs/ext2/dir.c 2010-05-30 22:33:06.790253891 +0200
+++ linux-2.6/fs/ext2/dir.c 2010-05-30 22:36:53.972003647 +0200
@@ -450,8 +450,7 @@ ino_t ext2_inode_by_name(struct inode *d
static int ext2_prepare_chunk(struct page *page, loff_t pos, unsigned len)
{
- return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0,
- &page, NULL, ext2_get_block);
+ return __block_write_begin(page, pos, len, ext2_get_block);
}
/* Releases the page */
Index: linux-2.6/fs/minix/inode.c
===================================================================
--- linux-2.6.orig/fs/minix/inode.c 2010-05-30 22:33:06.810255986 +0200
+++ linux-2.6/fs/minix/inode.c 2010-05-30 22:40:02.980254241 +0200
@@ -359,8 +359,7 @@ static int minix_readpage(struct file *f
int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len)
{
- return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0,
- &page, NULL, minix_get_block);
+ return __block_write_begin(page, pos, len, minix_get_block);
}
static int minix_write_begin(struct file *file, struct address_space *mapping,
Index: linux-2.6/fs/nilfs2/dir.c
===================================================================
--- linux-2.6.orig/fs/nilfs2/dir.c 2010-05-30 22:33:06.880005392 +0200
+++ linux-2.6/fs/nilfs2/dir.c 2010-05-30 22:36:53.982004974 +0200
@@ -83,8 +83,7 @@ static unsigned nilfs_last_byte(struct i
static int nilfs_prepare_chunk(struct page *page, unsigned from, unsigned to)
{
loff_t pos = page_offset(page) + from;
- return block_write_begin_newtrunc(NULL, page->mapping, pos, to - from,
- 0, &page, NULL, nilfs_get_block);
+ return __block_write_begin(page, pos, to - from, nilfs_get_block);
}
static void nilfs_commit_chunk(struct page *page,
Index: linux-2.6/fs/sysv/itree.c
===================================================================
--- linux-2.6.orig/fs/sysv/itree.c 2010-05-30 22:33:06.832007627 +0200
+++ linux-2.6/fs/sysv/itree.c 2010-05-30 22:40:02.987254172 +0200
@@ -461,8 +461,7 @@ static int sysv_readpage(struct file *fi
int sysv_prepare_chunk(struct page *page, loff_t pos, unsigned len)
{
- return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0,
- &page, NULL, get_block);
+ return __block_write_begin(page, pos, len, get_block);
}
static int sysv_write_begin(struct file *file, struct address_space *mapping,
Index: linux-2.6/fs/ufs/inode.c
===================================================================
--- linux-2.6.orig/fs/ufs/inode.c 2010-05-30 22:33:06.861257313 +0200
+++ linux-2.6/fs/ufs/inode.c 2010-05-30 22:40:02.996254591 +0200
@@ -561,8 +561,7 @@ static int ufs_readpage(struct file *fil
int ufs_prepare_chunk(struct page *page, loff_t pos, unsigned len)
{
- return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0,
- &page, NULL, ufs_getfrag_block);
+ return __block_write_begin(page, pos, len, ufs_getfrag_block);
}
static int ufs_write_begin(struct file *file, struct address_space *mapping,
Index: linux-2.6/include/linux/buffer_head.h
===================================================================
--- linux-2.6.orig/include/linux/buffer_head.h 2010-05-30 22:32:22.783254030 +0200
+++ linux-2.6/include/linux/buffer_head.h 2010-05-30 22:40:03.005253892 +0200
@@ -209,6 +209,8 @@ int block_write_begin_newtrunc(struct fi
int block_write_begin(struct file *, struct address_space *,
loff_t, unsigned, unsigned,
struct page **, void **, get_block_t*);
+int __block_write_begin(struct page *page, loff_t pos, unsigned len,
+ get_block_t *get_block);
int block_write_end(struct file *, struct address_space *,
loff_t, unsigned, unsigned,
struct page *, void *);
Index: linux-2.6/fs/ext3/inode.c
===================================================================
--- linux-2.6.orig/fs/ext3/inode.c 2010-05-30 22:28:18.676253821 +0200
+++ linux-2.6/fs/ext3/inode.c 2010-05-30 22:36:54.000003996 +0200
@@ -1196,8 +1196,7 @@ retry:
ret = PTR_ERR(handle);
goto out;
}
- ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
- ext3_get_block);
+ ret = __block_write_begin(page, pos, len, ext3_get_block);
if (ret)
goto write_begin_failed;
Index: linux-2.6/fs/ext4/inode.c
===================================================================
--- linux-2.6.orig/fs/ext4/inode.c 2010-05-30 22:28:18.646254240 +0200
+++ linux-2.6/fs/ext4/inode.c 2010-05-30 22:36:54.006004066 +0200
@@ -1578,11 +1578,9 @@ retry:
*pagep = page;
if (ext4_should_dioread_nolock(inode))
- ret = block_write_begin(file, mapping, pos, len, flags, pagep,
- fsdata, ext4_get_block_write);
+ ret = __block_write_begin(page, pos, len, ext4_get_block_write);
else
- ret = block_write_begin(file, mapping, pos, len, flags, pagep,
- fsdata, ext4_get_block);
+ ret = __block_write_begin(page, pos, len, ext4_get_block);
if (!ret && ext4_should_journal_data(inode)) {
ret = walk_page_buffers(handle, page_buffers(page),
@@ -1593,7 +1591,7 @@ retry:
unlock_page(page);
page_cache_release(page);
/*
- * block_write_begin may have instantiated a few blocks
+ * __block_write_begin may have instantiated a few blocks
* outside i_size. Trim these off again. Don't need
* i_size_read because we hold i_mutex.
*
@@ -3185,8 +3183,7 @@ retry:
}
*pagep = page;
- ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
- ext4_da_get_block_prep);
+ ret = __block_write_begin(page, pos, len, ext4_da_get_block_prep);
if (ret < 0) {
unlock_page(page);
ext4_journal_stop(handle);
Index: linux-2.6/fs/reiserfs/inode.c
===================================================================
--- linux-2.6.orig/fs/reiserfs/inode.c 2010-05-30 22:28:18.703254310 +0200
+++ linux-2.6/fs/reiserfs/inode.c 2010-05-30 22:36:54.013004695 +0200
@@ -2587,8 +2587,7 @@ static int reiserfs_write_begin(struct f
old_ref = th->t_refcount;
th->t_refcount++;
}
- ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
- reiserfs_get_block);
+ ret = __block_write_begin(page, pos, len, reiserfs_get_block);
if (ret && reiserfs_transaction_running(inode->i_sb)) {
struct reiserfs_transaction_handle *th = current->journal_info;
/* this gets a little ugly. If reiserfs_get_block returned an
next prev parent reply other threads:[~2010-05-30 20:50 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-30 20:49 [PATCH 0/6] first step toward the new truncate sequence Christoph Hellwig
2010-05-30 20:49 ` [PATCH 1/6] sort out blockdev_direct_IO variants Christoph Hellwig
2010-06-01 23:00 ` Jan Kara
2010-06-01 23:12 ` Christoph Hellwig
2010-06-01 23:16 ` Jan Kara
2010-05-30 20:49 ` [PATCH 2/6] get rid of nobh_write_begin_newtrunc Christoph Hellwig
2010-05-30 20:50 ` [PATCH 3/6] get rid of cont_write_begin_newtrunc Christoph Hellwig
2010-05-30 20:50 ` [PATCH 4/6] clean up write_begin usage for directories in pagecache Christoph Hellwig
2010-05-30 20:50 ` Christoph Hellwig [this message]
2010-05-31 8:10 ` [PATCH 5/6] introduce __block_write_begin Christoph Hellwig
2010-06-01 23:39 ` Jan Kara
2010-06-02 7:25 ` Christoph Hellwig
2010-06-02 9:47 ` Jan Kara
2010-05-30 20:50 ` [PATCH 6/6] get rid of block_write_begin_newtrunc Christoph Hellwig
2010-05-31 7:13 ` [PATCH 0/6] first step toward the new truncate sequence Nick Piggin
2010-05-31 7:38 ` Christoph Hellwig
2010-05-31 7:45 ` Nick Piggin
2010-05-31 9:50 ` Boaz Harrosh
2010-05-31 10:17 ` Boaz Harrosh
2010-05-31 13:15 ` Nick Piggin
2010-05-31 13:18 ` Christoph Hellwig
2010-05-31 13:21 ` Boaz Harrosh
2010-06-01 10:07 ` Christoph Hellwig
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=20100530205018.GF21002@lst.de \
--to=hch@lst.de \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
--cc=npiggin@suse.de \
--cc=viro@zeniv.linux.org.uk \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.