Commit 55de535e authored by Jens Axboe's avatar Jens Axboe
Browse files

Merge branch 'cached-zones' into for-6.19/block

This patch series implements a cached report zones using information
from the block layer zone write plugs and a new zone condition tracking.
This avoids having to execute slow report zones commands on the device
when for instance mounting file systems, which can significantly speed
things up, especially in setups with multiple SMR HDDs (e.g. a BTRFS
RAID volume).

The first patch improves handling of zone management commands. Patch 2
fixes zone resource updates and the following 3 patches cleanup the zone
code in preparation for introducing cached zone report support.
From patch 6 to 13, cached report zones is implemented and made
available to users with a new ioctl() command.

Finally, patches 14 and 15 introduce the use of cached report zones in
the mount operation of XFS and BTRFS.

Link: https://lore.kernel.org/linux-block/20251104212249.1075412-1-dlemoal@kernel.org/


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>

* cached-zones:
  xfs: use blkdev_report_zones_cached()
  btrfs: use blkdev_report_zones_cached()
  block: add zone write plug condition to debugfs zone_wplugs
  block: improve zone_wplugs debugfs attribute output
  block: introduce BLKREPORTZONESV2 ioctl
  block: introduce blkdev_report_zones_cached()
  block: introduce blkdev_get_zone_info()
  block: refactor blkdev_report_zones() code
  block: track zone conditions
  block: use zone condition to determine conventional zones
  block: reorganize struct blk_zone_wplug
  block: introduce disk_report_zone()
  block: cleanup blkdev_report_zones()
  block: freeze queue when updating zone resources
  block: handle zone management operations completions
parents f68ff6bc e04ccfc2
Loading
Loading
Loading
Loading
+627 −171

File changed.

Preview size limit exceeded, changes collapsed.

+14 −0
Original line number Diff line number Diff line
@@ -489,9 +489,23 @@ static inline bool blk_req_bio_is_zone_append(struct request *rq,
void blk_zone_write_plug_bio_merged(struct bio *bio);
void blk_zone_write_plug_init_request(struct request *rq);
void blk_zone_append_update_request_bio(struct request *rq, struct bio *bio);
void blk_zone_mgmt_bio_endio(struct bio *bio);
void blk_zone_write_plug_bio_endio(struct bio *bio);
static inline void blk_zone_bio_endio(struct bio *bio)
{
	/*
	 * Zone management BIOs may impact zone write plugs (e.g. a zone reset
	 * changes a zone write plug zone write pointer offset), but these
	 * operation do not go through zone write plugging as they may operate
	 * on zones that do not have a zone write
	 * plug. blk_zone_mgmt_bio_endio() handles the potential changes to zone
	 * write plugs that are present.
	 */
	if (op_is_zone_mgmt(bio_op(bio))) {
		blk_zone_mgmt_bio_endio(bio);
		return;
	}

	/*
	 * For write BIOs to zoned devices, signal the completion of the BIO so
	 * that the next write BIO can be submitted by zone write plugging.
+1 −0
Original line number Diff line number Diff line
@@ -581,6 +581,7 @@ static int blkdev_common_ioctl(struct block_device *bdev, blk_mode_t mode,
	case BLKGETDISKSEQ:
		return put_u64(argp, bdev->bd_disk->diskseq);
	case BLKREPORTZONE:
	case BLKREPORTZONEV2:
		return blkdev_report_zones_ioctl(bdev, cmd, arg);
	case BLKRESETZONE:
	case BLKOPENZONE:
+2 −1
Original line number Diff line number Diff line
@@ -143,7 +143,8 @@ int null_init_zoned_dev(struct nullb_device *dev, struct queue_limits *lim);
int null_register_zoned_dev(struct nullb *nullb);
void null_free_zoned_dev(struct nullb_device *dev);
int null_report_zones(struct gendisk *disk, sector_t sector,
		      unsigned int nr_zones, report_zones_cb cb, void *data);
		      unsigned int nr_zones,
		      struct blk_report_zones_args *args);
blk_status_t null_process_zoned_cmd(struct nullb_cmd *cmd, enum req_op op,
				    sector_t sector, sector_t nr_sectors);
size_t null_zone_valid_read_len(struct nullb *nullb,
+2 −2
Original line number Diff line number Diff line
@@ -191,7 +191,7 @@ void null_free_zoned_dev(struct nullb_device *dev)
}

int null_report_zones(struct gendisk *disk, sector_t sector,
		unsigned int nr_zones, report_zones_cb cb, void *data)
		unsigned int nr_zones, struct blk_report_zones_args *args)
{
	struct nullb *nullb = disk->private_data;
	struct nullb_device *dev = nullb->dev;
@@ -225,7 +225,7 @@ int null_report_zones(struct gendisk *disk, sector_t sector,
		blkz.capacity = zone->capacity;
		null_unlock_zone(dev, zone);

		error = cb(&blkz, i, data);
		error = disk_report_zone(disk, &blkz, i, args);
		if (error)
			return error;
	}
Loading