forked from Minki/linux
ext4: fix inline data error paths
The write_end() function must always unlock the page and drop its ref count, even on an error. Signed-off-by: Theodore Ts'o <tytso@mit.edu> Cc: stable@vger.kernel.org
This commit is contained in:
parent
1c83a9aab8
commit
eb5efbcb76
@ -943,8 +943,15 @@ int ext4_da_write_inline_data_end(struct inode *inode, loff_t pos,
|
||||
struct page *page)
|
||||
{
|
||||
int i_size_changed = 0;
|
||||
int ret;
|
||||
|
||||
copied = ext4_write_inline_data_end(inode, pos, len, copied, page);
|
||||
ret = ext4_write_inline_data_end(inode, pos, len, copied, page);
|
||||
if (ret < 0) {
|
||||
unlock_page(page);
|
||||
put_page(page);
|
||||
return ret;
|
||||
}
|
||||
copied = ret;
|
||||
|
||||
/*
|
||||
* No need to use i_size_read() here, the i_size
|
||||
|
@ -1330,8 +1330,11 @@ static int ext4_write_end(struct file *file,
|
||||
if (ext4_has_inline_data(inode)) {
|
||||
ret = ext4_write_inline_data_end(inode, pos, len,
|
||||
copied, page);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
unlock_page(page);
|
||||
put_page(page);
|
||||
goto errout;
|
||||
}
|
||||
copied = ret;
|
||||
} else
|
||||
copied = block_write_end(file, mapping, pos,
|
||||
@ -1433,10 +1436,16 @@ static int ext4_journalled_write_end(struct file *file,
|
||||
|
||||
BUG_ON(!ext4_handle_valid(handle));
|
||||
|
||||
if (ext4_has_inline_data(inode))
|
||||
copied = ext4_write_inline_data_end(inode, pos, len,
|
||||
copied, page);
|
||||
else if (unlikely(copied < len) && !PageUptodate(page)) {
|
||||
if (ext4_has_inline_data(inode)) {
|
||||
ret = ext4_write_inline_data_end(inode, pos, len,
|
||||
copied, page);
|
||||
if (ret < 0) {
|
||||
unlock_page(page);
|
||||
put_page(page);
|
||||
goto errout;
|
||||
}
|
||||
copied = ret;
|
||||
} else if (unlikely(copied < len) && !PageUptodate(page)) {
|
||||
copied = 0;
|
||||
ext4_journalled_zero_new_buffers(handle, page, from, to);
|
||||
} else {
|
||||
@ -1471,6 +1480,7 @@ static int ext4_journalled_write_end(struct file *file,
|
||||
*/
|
||||
ext4_orphan_add(handle, inode);
|
||||
|
||||
errout:
|
||||
ret2 = ext4_journal_stop(handle);
|
||||
if (!ret)
|
||||
ret = ret2;
|
||||
|
Loading…
Reference in New Issue
Block a user