Skip to content

Commit 452c8f6

Browse files
Christoph Hellwigaxboe
authored andcommitted
xfs: fix number of GC bvecs
GC scratch allocations can wrap around and use the same buffer twice, and the current code fails to account for that. So far this worked due to rounding in the block layer, but changes to the bio allocator drop the over-provisioning and generic/256 or generic/361 will now usually fail when running against the current block tree. Simplify the allocation to always pass the maximum value that is easier to verify, as a saving of up to one bvec per allocation isn't worth the effort to verify a complicated calculated value. Fixes: 102f444 ("xfs: rework zone GC buffer management") Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hans Holmberg <hans.holmberg@wdc.com> Link: https://patch.msgid.link/20260407140538.633364-2-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent affb5f6 commit 452c8f6

1 file changed

Lines changed: 10 additions & 9 deletions

File tree

fs/xfs/xfs_zone_gc.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,6 @@ xfs_zone_gc_start_chunk(
671671
struct xfs_inode *ip;
672672
struct bio *bio;
673673
xfs_daddr_t daddr;
674-
unsigned int len;
675674
bool is_seq;
676675

677676
if (xfs_is_shutdown(mp))
@@ -686,15 +685,16 @@ xfs_zone_gc_start_chunk(
686685
return false;
687686
}
688687

689-
len = XFS_FSB_TO_B(mp, irec.rm_blockcount);
690-
bio = bio_alloc_bioset(bdev,
691-
min(howmany(len, XFS_GC_BUF_SIZE) + 1, XFS_GC_NR_BUFS),
692-
REQ_OP_READ, GFP_NOFS, &data->bio_set);
693-
688+
/*
689+
* Scratch allocation can wrap around to the same buffer again,
690+
* provision an extra bvec for that case.
691+
*/
692+
bio = bio_alloc_bioset(bdev, XFS_GC_NR_BUFS + 1, REQ_OP_READ, GFP_NOFS,
693+
&data->bio_set);
694694
chunk = container_of(bio, struct xfs_gc_bio, bio);
695695
chunk->ip = ip;
696696
chunk->offset = XFS_FSB_TO_B(mp, irec.rm_offset);
697-
chunk->len = len;
697+
chunk->len = XFS_FSB_TO_B(mp, irec.rm_blockcount);
698698
chunk->old_startblock =
699699
xfs_rgbno_to_rtb(iter->victim_rtg, irec.rm_startblock);
700700
chunk->new_daddr = daddr;
@@ -708,8 +708,9 @@ xfs_zone_gc_start_chunk(
708708
bio->bi_iter.bi_sector = xfs_rtb_to_daddr(mp, chunk->old_startblock);
709709
bio->bi_end_io = xfs_zone_gc_end_io;
710710
xfs_zone_gc_add_data(chunk);
711-
data->scratch_head = (data->scratch_head + len) % data->scratch_size;
712-
data->scratch_available -= len;
711+
data->scratch_head =
712+
(data->scratch_head + chunk->len) % data->scratch_size;
713+
data->scratch_available -= chunk->len;
713714

714715
XFS_STATS_INC(mp, xs_gc_read_calls);
715716

0 commit comments

Comments
 (0)