--- e/fs/ext4/ext4.h 2022-08-19 19:46:26.317620400 +0800 +++ f/fs/ext4/ext4.h 2022-08-19 19:50:41.005830300 +0800 @@ -1081,6 +1081,7 @@ struct ext4_inode_info { /* Protect concurrent accesses on i_fc_lblk_start, i_fc_lblk_len */ struct mutex i_fc_lock; + struct rw_semaphore i_bmap_sem; /* * i_disksize keeps track of what the inode size is ON DISK, not * in memory. During truncate, i_size is set to the new size by --- e/fs/ext4/file.c 2022-08-19 19:45:25.253573600 +0800 +++ f/fs/ext4/file.c 2022-08-19 20:04:13.481483600 +0800 @@ -265,11 +265,13 @@ static ssize_t ext4_buffered_write_iter( ret = ext4_write_checks(iocb, from); if (ret <= 0) goto out; + down_write(&EXT4_I(inode)->i_bmap_sem); current->backing_dev_info = inode_to_bdi(inode); ret = generic_perform_write(iocb, from); current->backing_dev_info = NULL; + up_write(&EXT4_I(inode)->i_bmap_sem); out: inode_unlock(inode); if (likely(ret > 0)) { --- e/fs/ext4/inode.c 2022-08-19 19:44:33.471445500 +0800 +++ f/fs/ext4/inode.c 2022-08-19 20:00:25.319110800 +0800 @@ -3154,7 +3154,7 @@ static sector_t ext4_bmap(struct address sector_t ret = 0; int err; - inode_lock_shared(inode); + down_read(&EXT4_I(inode)->i_bmap_sem); /* * We can get here for an inline file via the FIBMAP ioctl */ @@ -3204,7 +3204,7 @@ static sector_t ext4_bmap(struct address ret = iomap_bmap(mapping, block, &ext4_iomap_ops); out: - inode_unlock_shared(inode); + up_read(&EXT4_I(inode)->i_bmap_sem); return ret; } --- e/fs/ext4/super.c 2022-08-19 19:53:38.208033600 +0800 +++ f/fs/ext4/super.c 2022-08-19 19:55:01.503030300 +0800 @@ -1405,6 +1405,7 @@ static void init_once(void *foo) INIT_LIST_HEAD(&ei->i_orphan); init_rwsem(&ei->xattr_sem); init_rwsem(&ei->i_data_sem); + init_rwsem(&ei->i_bmap_sem); inode_init_once(&ei->vfs_inode); ext4_fc_init_inode(&ei->vfs_inode); }