Skip to content

Commit 776a838

Browse files
naotakdave
authored andcommitted
btrfs: zoned: wait for data BG to be finished on direct IO allocation
Running the fio command below on a ZNS device results in "Resource temporarily unavailable" error. $ sudo fio --name=w --directory=/mnt --filesize=1GB --bs=16MB --numjobs=16 \ --rw=write --ioengine=libaio --iodepth=128 --direct=1 fio: io_u error on file /mnt/w.2.0: Resource temporarily unavailable: write offset=117440512, buflen=16777216 fio: io_u error on file /mnt/w.2.0: Resource temporarily unavailable: write offset=134217728, buflen=16777216 ... This happens because -EAGAIN error returned from btrfs_reserve_extent() called from btrfs_new_extent_direct() is spilling over to the userland. btrfs_reserve_extent() returns -EAGAIN when there is no active zone available. Then, the caller should wait for some other on-going IO to finish a zone and retry the allocation. This logic is already implemented for buffered write in cow_file_range(), but it is missing for the direct IO counterpart. Implement the same logic for it. Reported-by: Shinichiro Kawasaki <shinichiro.kawasaki@wdc.com> Fixes: 2ce543f ("btrfs: zoned: wait until zone is finished when allocation didn't progress") CC: stable@vger.kernel.org # 6.1+ Tested-by: Shinichiro Kawasaki <shinichiro.kawasaki@wdc.com> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent dfcb03a commit 776a838

1 file changed

Lines changed: 7 additions & 0 deletions

File tree

fs/btrfs/inode.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6979,8 +6979,15 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode,
69796979
int ret;
69806980

69816981
alloc_hint = get_extent_allocation_hint(inode, start, len);
6982+
again:
69826983
ret = btrfs_reserve_extent(root, len, len, fs_info->sectorsize,
69836984
0, alloc_hint, &ins, 1, 1);
6985+
if (ret == -EAGAIN) {
6986+
ASSERT(btrfs_is_zoned(fs_info));
6987+
wait_on_bit_io(&inode->root->fs_info->flags, BTRFS_FS_NEED_ZONE_FINISH,
6988+
TASK_UNINTERRUPTIBLE);
6989+
goto again;
6990+
}
69846991
if (ret)
69856992
return ERR_PTR(ret);
69866993

0 commit comments

Comments
 (0)