Linux block layer
 help / color / mirror / Atom feed
From: Jens Axboe <axboe@kernel.dk>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: "linux-block@vger.kernel.org" <linux-block@vger.kernel.org>
Subject: Re: [GIT PULL] Block updates for 7.4-rc
Date: Wed, 21 Oct 2026 09:10:58 -0600	[thread overview]
Message-ID: <efe0abd7-edf4-4d2e-a8e8-be4203d7ac3b@kernel.dk> (raw)
In-Reply-To: <3b7e92f1-77a7-4bf7-a942-83de345bfd1a@kernel.dk>

On 10/21/26 8:43 AM, Jens Axboe wrote:
> Hi Linus,
> 
> Here are the block updates and fixes queued up for the 7.4 merge
> window. This pull request contains:

Completely forgot to mention that this merge will throw conflicts. Both
block/bio.c and block/blk-zoned.c will need resolving. Details:

bio.c hits bounce-buffering changes already in your tree. The resolution
keeps the maxlen parameter, uses the atomic-write failure path, and
keeps the multi-page unpinning in align_down() - which loses the bvec
argument it grew here, as it derives that internally again.

blk-zoned.c is Damien's zone revalidation rework colliding with the zone
report fixes that went in during 7.3.

Resolved as below, which matches what I've had in linux-next for a
while:

diff --cc block/bio.c
index b48091c7663f,41d9f1c5992d..06f805d3866a
--- a/block/bio.c
+++ b/block/bio.c
@@@ -1223,10 -1218,10 +1238,11 @@@ static void bvec_unpin(struct bio_vec *
   * for the next iteration.
   */
  static int bio_iov_iter_align_down(struct bio *bio, struct iov_iter *iter,
 -				   struct bio_vec *bv, unsigned len_align_mask)
 +				   unsigned len_align_mask)
  {
 +	struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1];
  	size_t nbytes = bio->bi_iter.bi_size & len_align_mask;
+ 	unsigned int npages;

  	if (!nbytes)
  		return 0;
@@@ -1304,10 -1308,11 +1330,12 @@@ static inline bool bio_iov_bvec_aligned
   * is returned only if 0 pages could be pinned.
   */
  int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter,
 -			   unsigned mem_align_mask, unsigned len_align_mask)
 +			   unsigned maxlen, unsigned mem_align_mask,
 +			   unsigned len_align_mask)
  {
  	iov_iter_extraction_t flags = 0;
+ 	struct iov_iter saved_iter;
+ 	int ret;

  	if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)))
  		return -EIO;
@@@ -1328,34 -1331,50 +1356,49 @@@
  	if (bio->bi_bdev && blk_queue_pci_p2pdma(bio->bi_bdev->bd_disk->queue))
  		flags |= ITER_ALLOW_P2PDMA;

+ 	saved_iter = *iter;
  	do {
- 		ssize_t ret;
+ 		ssize_t size;

- 		ret = iov_iter_extract_bvecs(iter, bio->bi_io_vec,
+ 		size = iov_iter_extract_bvecs(iter, bio->bi_io_vec,
 -				BIO_MAX_SIZE - bio->bi_iter.bi_size,
 +				maxlen - bio->bi_iter.bi_size,
  				&bio->bi_vcnt, bio->bi_max_vecs,
  				mem_align_mask, flags);
- 		if (ret <= 0) {
- 			/*
- 			 * A misaligned vector fails the whole I/O.  Release any
- 			 * pages pinned by earlier iterations before returning
- 			 * since this bio won't be submitted to release them.
- 			 */
- 			if (ret == -EINVAL) {
- 				bio_release_pages(bio, false);
- 				bio_clear_flag(bio, BIO_PAGE_PINNED);
- 				bio->bi_vcnt = 0;
- 			}
+ 		if (size <= 0) {
+ 			/* A misaligned vector fails the whole I/O */
+ 			if (size == -EINVAL)
+ 				goto out_release_pages;
  			if (!bio->bi_vcnt)
- 				return ret;
+ 				return size;
  			break;
  		}
- 		bio->bi_iter.bi_size += ret;
+ 		bio->bi_iter.bi_size += size;
  	} while (iov_iter_count(iter) && !bio_full(bio, 0));

  	if (is_pci_p2pdma_page(bio->bi_io_vec->bv_page))
  		bio->bi_opf |= REQ_NOMERGE;
- 	return bio_iov_iter_align_down(bio, iter, len_align_mask);
 -	ret = bio_iov_iter_align_down(bio, iter,
 -			&bio->bi_io_vec[bio->bi_vcnt - 1], len_align_mask);
++	ret = bio_iov_iter_align_down(bio, iter, len_align_mask);
+ 	if (ret)
+ 		return ret;
+
+ 	/*
+ 	 * An atomic write is submitted as a single bio, so it has to cover
+ 	 * the whole iterator or it would be torn.
+ 	 */
+ 	if ((bio->bi_opf & REQ_ATOMIC) && iov_iter_count(iter))
+ 		goto out_release_pages;
+ 	return 0;
+
+ out_release_pages:
+ 	/*
+ 	 * Release the pages pinned so far before failing, since this bio won't
+ 	 * be submitted to release them.
+ 	 */
+ 	bio_release_pages(bio, false);
+ 	bio_clear_flag(bio, BIO_PAGE_PINNED);
+ 	bio->bi_vcnt = 0;
+ 	*iter = saved_iter;
+ 	return -EINVAL;
  }

diff --cc block/blk-zoned.c
index 475aa16bc41a,ec510d66dfe2..d8688a3d8314
--- a/block/blk-zoned.c
+++ b/block/blk-zoned.c
@@@ -1860,6 -2028,16 +2028,21 @@@ void disk_init_zone_resources(struct ge
  	init_completion(&disk->zone_wplugs_worker_bio_done);
  }

+ static unsigned int disk_get_nr_zones(struct gendisk *disk, sector_t capacity)
+ {
+ 	struct queue_limits *lim = &disk->queue->limits;
++	unsigned long long nr_zones;
+
+ 	if (!capacity || !lim->chunk_sectors)
+ 		return 0;
+
 -	return DIV_ROUND_UP_ULL(capacity, lim->chunk_sectors);
++	nr_zones = DIV_ROUND_UP_ULL(capacity, lim->chunk_sectors);
++	if (nr_zones > UINT_MAX)
++		return 0;
++
++	return nr_zones;
+ }
+
  /*
   * For the size of a disk zone write plug hash table, use the size of the
   * zone write plug mempool, which is the maximum of the disk open zones and
@@@ -2014,46 -2192,18 +2197,20 @@@ struct blk_revalidate_zone_args
  	sector_t	sector;
  };

- static int disk_revalidate_zone_resources(struct gendisk *disk,
- 				struct blk_revalidate_zone_args *args)
+ static int disk_init_revalidate_args(struct gendisk *disk,
+ 				     struct blk_revalidate_zone_args *args)
  {
- 	struct queue_limits *lim = &disk->queue->limits;
- 	unsigned long long nr_zones;
- 	unsigned int pool_size;
- 	int ret = 0;
-
  	args->disk = disk;
- 	nr_zones = DIV_ROUND_UP_ULL(get_capacity(disk), lim->chunk_sectors);
- 	if (nr_zones > UINT_MAX) {
- 		pr_warn("%s: Too many zones (%llu)\n", disk->disk_name, nr_zones);
- 		return -EINVAL;
- 	}
- 	args->nr_zones = nr_zones;
+ 	args->nr_zones = disk_get_nr_zones(disk, args->capacity);
++	if (!args->nr_zones)
++		return -ENODEV;

  	/* Cached zone conditions: 1 byte per zone */
- 	args->zones_cond = kzalloc(args->nr_zones, GFP_NOIO);
- 	if (!args->zones_cond)
+ 	args->zones_state = kzalloc(args->nr_zones, GFP_NOIO);
+ 	if (!args->zones_state)
  		return -ENOMEM;

- 	if (!disk_need_zone_resources(disk))
- 		return 0;
-
- 	/*
- 	 * If the device has no limit on the maximum number of open and active
- 	 * zones, use BLK_ZONE_WPLUG_DEFAULT_POOL_SIZE.
- 	 */
- 	pool_size = max(lim->max_open_zones, lim->max_active_zones);
- 	if (!pool_size)
- 		pool_size =
- 			min(BLK_ZONE_WPLUG_DEFAULT_POOL_SIZE, args->nr_zones);
-
- 	if (!disk->zone_wplugs_hash) {
- 		ret = disk_alloc_zone_resources(disk, pool_size);
- 		if (ret)
- 			kfree(args->zones_cond);
- 	}
-
- 	return ret;
+ 	return 0;
  }

  /*

-- 
Jens Axboe

  reply	other threads:[~2026-10-21 15:11 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-21 14:43 [GIT PULL] Block updates for 7.4-rc Jens Axboe
2026-10-21 15:10 ` Jens Axboe [this message]
2026-10-25  0:18   ` Linus Torvalds
2026-10-25  3:09     ` Jens Axboe
2026-10-25  0:20 ` pr-tracker-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=efe0abd7-edf4-4d2e-a8e8-be4203d7ac3b@kernel.dk \
    --to=axboe@kernel.dk \
    --cc=linux-block@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox