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
next prev parent 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