diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext4/inode.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 7e22e7636834..f881e3484481 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1073,7 +1073,9 @@ static int ext4_writeback_write_end(struct file *file, * set the buffer to be dirty, since in data=journalled mode we need * to call ext4_handle_dirty_metadata() instead. */ -static void zero_new_buffers(struct page *page, unsigned from, unsigned to) +static void ext4_journalled_zero_new_buffers(handle_t *handle, + struct page *page, + unsigned from, unsigned to) { unsigned int block_start = 0, block_end; struct buffer_head *head, *bh; @@ -1090,7 +1092,7 @@ static void zero_new_buffers(struct page *page, unsigned from, unsigned to) size = min(to, block_end) - start; zero_user(page, start, size); - set_buffer_uptodate(bh); + write_end_fn(handle, bh); } clear_buffer_new(bh); } @@ -1118,16 +1120,19 @@ static int ext4_journalled_write_end(struct file *file, BUG_ON(!ext4_handle_valid(handle)); - if (copied < len) { - if (!PageUptodate(page)) - copied = 0; - zero_new_buffers(page, from+copied, to); + if (unlikely(copied < len) && !PageUptodate(page)) { + copied = 0; + ext4_journalled_zero_new_buffers(handle, page, from, to); + } else { + if (unlikely(copied < len)) + ext4_journalled_zero_new_buffers(handle, page, + from + copied, to); + ret = walk_page_buffers(handle, page_buffers(page), from, + from + copied, &partial, + write_end_fn); + if (!partial) + SetPageUptodate(page); } - - ret = walk_page_buffers(handle, page_buffers(page), from, - to, &partial, write_end_fn); - if (!partial) - SetPageUptodate(page); new_i_size = pos + copied; if (new_i_size > inode->i_size) i_size_write(inode, pos+copied); |