hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IA5XLM CVE: NA
--------------------------------
Ext4 should check the return value of ext4_disable_buffered_iomap_aops() before moving extents, otherwise the EXT4_STATE_BUFFERED_IOMAP state is not cleared from the inode, which could trigger the WARNON in function _ext4_get_block().
Fixes: 2a158d544250 ("ext4: fall back to buffer_head path for defrag") Signed-off-by: Zhihao Cheng chengzhihao@huaweicloud.com --- fs/ext4/move_extent.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c index f58c0cb4dd76..afd7869cae9a 100644 --- a/fs/ext4/move_extent.c +++ b/fs/ext4/move_extent.c @@ -640,10 +640,16 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk, inode_dio_wait(donor_inode);
/* Fallback to buffer_head aops for inodes with buffered iomap aops */ - if (ext4_test_inode_state(orig_inode, EXT4_STATE_BUFFERED_IOMAP)) - ext4_disable_buffered_iomap_aops(orig_inode); - if (ext4_test_inode_state(donor_inode, EXT4_STATE_BUFFERED_IOMAP)) - ext4_disable_buffered_iomap_aops(donor_inode); + if (ext4_test_inode_state(orig_inode, EXT4_STATE_BUFFERED_IOMAP)) { + ret = ext4_disable_buffered_iomap_aops(orig_inode); + if (ret) + goto out_unlock; + } + if (ext4_test_inode_state(donor_inode, EXT4_STATE_BUFFERED_IOMAP)) { + ret = ext4_disable_buffered_iomap_aops(donor_inode); + if (ret) + goto out_unlock; + }
/* Protect extent tree against block allocations via delalloc */ ext4_double_down_write_data_sem(orig_inode, donor_inode); @@ -728,6 +734,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk,
ext4_free_ext_path(path); ext4_double_up_write_data_sem(orig_inode, donor_inode); +out_unlock: unlock_two_nondirectories(orig_inode, donor_inode);
return ret;