mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
ext4: fix data corruption in data=journal mode
am: a5a9cf387d
Change-Id: Ia3c5c062ed2c7f59128ea30be63a55ef69b20d20
This commit is contained in:
@@ -1391,7 +1391,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;
|
||||
@@ -1408,7 +1410,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);
|
||||
}
|
||||
@@ -1441,15 +1443,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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user