mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 11:50:43 +09:00
ext4: fix data corruption in data=journal mode
am: 9d636818db
Change-Id: Idc4320c3f0fa867216d8770b5ad186226e61152a
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user