As same as with other IO submission, we must unlock a block group for the next allocation. Signed-off-by: Naohiro Aota <naohiro.aota@xxxxxxx> --- fs/btrfs/inode.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index e09089e24a8f..44658590c6e8 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -60,6 +60,7 @@ struct btrfs_dio_data { u64 reserve; u64 unsubmitted_oe_range_start; u64 unsubmitted_oe_range_end; + u64 alloc_end; int overwrite; }; @@ -7787,6 +7788,12 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map, } } + if (dio_data->alloc_end) { + btrfs_hmzoned_data_io_unlock_logical(fs_info, + dio_data->alloc_end - 1); + dio_data->alloc_end = 0; + } + /* this will cow the extent */ len = bh_result->b_size; free_extent_map(em); @@ -7818,6 +7825,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map, WARN_ON(dio_data->reserve < len); dio_data->reserve -= len; dio_data->unsubmitted_oe_range_end = start + len; + dio_data->alloc_end = em->block_start + (start - em->start) + len; current->journal_info = dio_data; out: return ret; @@ -8585,6 +8593,7 @@ static void btrfs_submit_direct(struct bio *dio_bio, struct inode *inode, struct btrfs_io_bio *io_bio; bool write = (bio_op(dio_bio) == REQ_OP_WRITE); int ret = 0; + u64 disk_bytenr, len; bio = btrfs_bio_clone(dio_bio); @@ -8628,7 +8637,18 @@ static void btrfs_submit_direct(struct bio *dio_bio, struct inode *inode, dio_data->unsubmitted_oe_range_end; } + disk_bytenr = dip->disk_bytenr; + len = dip->bytes; ret = btrfs_submit_direct_hook(dip); + if (write) { + struct btrfs_dio_data *dio_data = current->journal_info; + + if (disk_bytenr + len == dio_data->alloc_end) { + btrfs_hmzoned_data_io_unlock_logical( + btrfs_sb(inode->i_sb), disk_bytenr); + dio_data->alloc_end = 0; + } + } if (!ret) return; @@ -8804,6 +8824,11 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) btrfs_delalloc_release_space(inode, data_reserved, offset, count - (size_t)ret, true); btrfs_delalloc_release_extents(BTRFS_I(inode), count); + if (dio_data.alloc_end) { + pr_info("unlock final direct %llu", dio_data.alloc_end); + btrfs_hmzoned_data_io_unlock_logical( + fs_info, dio_data.alloc_end - 1); + } } out: if (wakeup) -- 2.24.0