Make the error legs similar to ext4_convert_inline_data_to_extent(), now that we have even more "unlock_page(); put_page();" statements. While in there, do similarly for the semaphore and label "convert:". Signed-off-by: Mauricio Faria de Oliveira <mfo@xxxxxxxxxxxxx> --- fs/ext4/inline.c | 56 +++++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 9bb85e06854d..3d370b04a740 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -684,9 +684,13 @@ int ext4_try_to_write_inline_data(struct address_space *mapping, handle_t *handle; struct page *page; struct ext4_iloc iloc; + bool convert = false; + bool sem_held = false; - if (pos + len > ext4_get_max_inline_size(inode)) - goto convert; + if (pos + len > ext4_get_max_inline_size(inode)) { + convert = true; + goto out_convert; + } ret = ext4_get_inode_loc(inode, &iloc); if (ret) @@ -717,6 +721,7 @@ int ext4_try_to_write_inline_data(struct address_space *mapping, put_page(page); ret = PTR_ERR(handle); handle = NULL; + page = NULL; goto out; } @@ -732,58 +737,47 @@ int ext4_try_to_write_inline_data(struct address_space *mapping, wait_for_stable_page(page); ret = ext4_prepare_inline_data(handle, inode, pos + len); - if (ret && ret != -ENOSPC) { - unlock_page(page); - put_page(page); + if (ret) { + /* If don't have space in inline inode, convert it to extent. */ + convert = (ret == -ENOSPC); goto out; } - /* We don't have space in inline inode, so convert it to extent. */ - if (ret == -ENOSPC) { - unlock_page(page); - put_page(page); - ext4_journal_stop(handle); - brelse(iloc.bh); - goto convert; - } - ret = ext4_journal_get_write_access(handle, iloc.bh); - if (ret) { - unlock_page(page); - put_page(page); + if (ret) goto out; - } *pagep = page; down_read(&EXT4_I(inode)->xattr_sem); + sem_held = true; if (!ext4_has_inline_data(inode)) { ret = 0; - unlock_page(page); - put_page(page); - goto out_up_read; + goto out; } if (!PageUptodate(page)) { ret = ext4_read_inline_page(inode, page); - if (ret < 0) { - unlock_page(page); - put_page(page); - goto out_up_read; - } + if (ret < 0) + goto out; } ret = 1; handle = NULL; -out_up_read: - up_read(&EXT4_I(inode)->xattr_sem); out: + if (page && (ret != 1)) { + unlock_page(page); + put_page(page); + } + if (sem_held) + up_read(&EXT4_I(inode)->xattr_sem); if (handle && (ret != 1)) ext4_journal_stop(handle); brelse(iloc.bh); +out_convert: + if (convert) + return ext4_convert_inline_data_to_extent(mapping, + inode, flags); return ret; -convert: - return ext4_convert_inline_data_to_extent(mapping, - inode, flags); } int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len, -- 2.20.1