Commit 60dc5ea6 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

block: take chunk_sectors into account in bio_split_write_zeroes



For zoned devices, write zeroes must be split at the zone boundary
which is represented as chunk_sectors.  For other uses like the
internally RAIDed NVMe devices it is probably at least useful.

Enhance get_max_io_size to know about write zeroes and use it in
bio_split_write_zeroes.  Also add a comment about the seemingly
nonsensical zero max_write_zeroes limit.

Fixes: 885fa13f ("block: implement splitting of REQ_OP_WRITE_ZEROES bios")
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDamien Le Moal <dlemoal@kernel.org>
Link: https://lore.kernel.org/r/20241104062647.91160-2-hch@lst.de


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 4cf58d95
Loading
Loading
Loading
Loading
+23 −12
Original line number Diff line number Diff line
@@ -171,17 +171,6 @@ struct bio *bio_split_discard(struct bio *bio, const struct queue_limits *lim,
	return bio_submit_split(bio, split_sectors);
}

struct bio *bio_split_write_zeroes(struct bio *bio,
		const struct queue_limits *lim, unsigned *nsegs)
{
	*nsegs = 0;
	if (!lim->max_write_zeroes_sectors)
		return bio;
	if (bio_sectors(bio) <= lim->max_write_zeroes_sectors)
		return bio;
	return bio_submit_split(bio, lim->max_write_zeroes_sectors);
}

static inline unsigned int blk_boundary_sectors(const struct queue_limits *lim,
						bool is_atomic)
{
@@ -216,7 +205,9 @@ static inline unsigned get_max_io_size(struct bio *bio,
	 * We ignore lim->max_sectors for atomic writes because it may less
	 * than the actual bio size, which we cannot tolerate.
	 */
	if (is_atomic)
	if (bio_op(bio) == REQ_OP_WRITE_ZEROES)
		max_sectors = lim->max_write_zeroes_sectors;
	else if (is_atomic)
		max_sectors = lim->atomic_write_max_sectors;
	else
		max_sectors = lim->max_sectors;
@@ -403,6 +394,26 @@ struct bio *bio_split_zone_append(struct bio *bio,
	return bio_submit_split(bio, split_sectors);
}

struct bio *bio_split_write_zeroes(struct bio *bio,
		const struct queue_limits *lim, unsigned *nsegs)
{
	unsigned int max_sectors = get_max_io_size(bio, lim);

	*nsegs = 0;

	/*
	 * An unset limit should normally not happen, as bio submission is keyed
	 * off having a non-zero limit.  But SCSI can clear the limit in the
	 * I/O completion handler, and we can race and see this.  Splitting to a
	 * zero limit obviously doesn't make sense, so band-aid it here.
	 */
	if (!max_sectors)
		return bio;
	if (bio_sectors(bio) <= max_sectors)
		return bio;
	return bio_submit_split(bio, max_sectors);
}

/**
 * bio_split_to_limits - split a bio to fit the queue limits
 * @bio:     bio to be split