|
@@ -1385,7 +1385,9 @@ errout:
|
|
|
* 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;
|
|
@@ -1402,7 +1404,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);
|
|
|
}
|
|
@@ -1434,15 +1436,16 @@ static int ext4_journalled_write_end(struct file *file,
|
|
|
if (ext4_has_inline_data(inode))
|
|
|
copied = ext4_write_inline_data_end(inode, pos, len,
|
|
|
copied, page);
|
|
|
- else {
|
|
|
- if (copied < len) {
|
|
|
- if (!PageUptodate(page))
|
|
|
- copied = 0;
|
|
|
- zero_new_buffers(page, from+copied, to);
|
|
|
- }
|
|
|
-
|
|
|
+ else 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 = ext4_walk_page_buffers(handle, page_buffers(page), from,
|
|
|
- to, &partial, write_end_fn);
|
|
|
+ from + copied, &partial,
|
|
|
+ write_end_fn);
|
|
|
if (!partial)
|
|
|
SetPageUptodate(page);
|
|
|
}
|