[PATCH v2 0/4] block/nvme: split path limits for namespace heads

Yao Sang <[email protected]> Thu, 6 Aug 2026 10:46:54 +0800
Newsgroups org.infradead.lists.linux-nvme,org.kernel.vger.linux-block
Message-ID <[email protected]>
An NVMe namespace head and each path refer to the same namespace. Using
queue_limits_stack_bdev() for the head treats a path as a bottom-device
range and applies the full blk_stack_limits() model. That model is for
generic stacked devices, not for an NVMe namespace head.

For a generic stacked device, the top device maps its data to a range in a
bottom device. blk_stack_limits() must then combine the limits that depend
on that bottom-device range with the limits that must be supported by every
bottom queue. For an NVMe namespace head, all paths address the same LBA
space, so the head should refresh namespace layout values from the
namespace scan and only combine the path limits across paths.

This series makes that split explicit. Topology limits are the block size,
alignment, io_min, io_opt and chunk_sectors values that depend on where the
top device data starts in the bottom device. Path limits are the all-path
execution feature bits, such as NOWAIT, POLL and PCI_P2PDMA, and hardware
limits that every queue which may execute an I/O must support. Operation
and resource limits, such as discard, write zeroes, atomic writes and zoned
resources, keep their own rules.

The first block patch moves the topology work into a static helper. The
second block patch moves the path feature checks and the sector, segment,
integrity segment and DMA alignment updates into blk_stack_path_limits().
The final patch exports that helper and the existing atomic write helper
when adding the NVMe namespace head caller. Existing callers of
blk_stack_limits() continue to use the full function with no behavior
change.

The topology helper uses start, the first data sector in the bottom device
used by the top device, when calculating alignment_offset. A failed
topology check sets BLK_FLAG_MISALIGNED and makes blk_stack_limits()
return -1. This keeps the existing behavior and only moves the code into
the helper. The atomic write helper uses start only in
blk_atomic_write_start_sect_aligned(); a failed check disables atomic
writes without changing the return value. Keep these parts separate even
though both use start. The existing discard alignment handling also
remains in blk_stack_limits().

Changes since v1:
- factor block size and alignment handling out of blk_stack_limits();
- factor the explicitly listed all-path feature and hardware limit updates
  into a block helper;
- export the block helpers only when adding the NVMe caller;
- retain the existing atomic write helper name and parameter types.

Tests:
- blktests nvme/004, 005, 006, 008, 010, 012, 014, 016, 017, 018,
  019, 021, 022, 023, 025, 026, 027, 028, 029, 030, 031, 040, 041,
  042, 043, 044, 045, 049, 051, 052, 053, 054, 057, 058, 059, 065,
  067 and 068 passed.
- blktests zbd/001, 003, 004, 005, 006, 008, 009, 011, 012, and 013
  passed.
- blktests block/003, 004, and 012, and scsi/009 and 010 passed.
- xfstests xfs/643, xfs/646, generic/765, and generic/773 passed.

Link to v1:
https://lore.kernel.org/all/[email protected]/

Yao Sang (4):
  nvme: factor namespace-head queue-limit update
  block: factor block size and alignment handling out of
    blk_stack_limits
  block: factor out path limit stacking
  block, nvme: use lower-level limit helpers for namespace heads

 block/blk-settings.c     | 171 +++++++++++++++++++++++---------------
 drivers/nvme/host/core.c | 169 +++++++++++++++++++++++++++------------
 include/linux/blkdev.h   |   4 +
 3 files changed, 224 insertions(+), 120 deletions(-)

-- 
2.25.1