diff options
author | Jan Kara <jack@suse.cz> | 2017-03-12 08:18:16 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2017-03-12 08:18:16 +0000 |
commit | 8b2bd3ddf4ecbde7032ed514b8bd7c73b493b222 (patch) | |
tree | f24c752c32cf2c3ecd318e687a20f61d1f65dcd8 /fs/ext4/inode.c | |
parent | 3e0e74cef5424866f16f724f54bf7ea29264131f (diff) | |
parent | 9d636818dbac53c07c1bf7aa006c06ec32253187 (diff) |
ext4: fix data corruption in data=journal mode
am: 9d636818db
Change-Id: Idc4320c3f0fa867216d8770b5ad186226e61152a
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 790961e33961..8a08807359b5 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1232,7 +1232,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; @@ -1249,7 +1251,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); } @@ -1282,15 +1284,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); } |