+2
−0
Loading
Offering: HULK hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IAODWM -------------------------------- The writeback process and error branch in writeback process may concurrently access extent tree, which leads to wrong da reservation count is calculated, specifically: write(4M) // folio 0, 1 are dirty wb_workfn fsync ext4_iomap_writepages iomap_do_writepage // writeback folio 0 iomap_writepage_map_blocks ext4_iomap_map_blocks ext4_iomap_map_one_extent ext4_map_create_blocks // down write(EXT4_I(inode)->i_data_sem) ext4_ext_map_blocks ext4_da_update_reserve_space // da reservation becomes 0 . . >> EIO occurs, journal is aborted << . ext4_sync_file . file_write_and_wait_range . do_writepages // writeback folio 1 . ext4_iomap_writepages . iomap_writepage_map_blocks . map_blocks // failed . discard_folio // error branch . ext4_es_remove_extent . // scan extents, delayed es is 512 . ext4_da_release_space . // da reservation count, 0 < 512 . WARN_ON(1) ext4_es_insert_extent // convert delayed es to unwritten status Since all changes on extent tree are protected by holding EXT4_I(inode)->i_data_sem, fix the problem by adding the lock while doing ext4_es_remove_extent(). Fixes: 7f6416dc ("ext4: implement writeback iomap path") Signed-off-by:Zhihao Cheng <chengzhihao1@huawei.com>