[PATCH v3 4/5] block: factor atomic write hardware limit stacking

Yao Sang sangyao at kylinos.cn
Fri Aug 21 03:10:49 PDT 2026


blk_stack_atomic_writes_limits() stacks atomic write hardware limits and
checks whether @start meets the bottom-device alignment. Only the start
check depends on the top-to-bottom mapping.

Factor hardware limit stacking into blk_stack_atomic_writes_hw_limits()
so same-LBA multipath can stack atomic write limits without checking a
mapped start sector.

There is no behavior change for existing callers.

Signed-off-by: Yao Sang <sangyao at kylinos.cn>
---
 block/blk-settings.c | 31 +++++++++++++++++++++----------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/block/blk-settings.c b/block/blk-settings.c
index f1a2e4fe4e77..eaba38370657 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -653,6 +653,14 @@ static unsigned int blk_round_down_sectors(unsigned int sectors, unsigned int lb
 	return sectors;
 }
 
+static void blk_clear_atomic_write_limits(struct queue_limits *lim)
+{
+	lim->atomic_write_hw_max = 0;
+	lim->atomic_write_hw_unit_max = 0;
+	lim->atomic_write_hw_unit_min = 0;
+	lim->atomic_write_hw_boundary = 0;
+}
+
 /* Check if second and later bottom devices are compliant */
 static bool blk_stack_atomic_writes_tail(struct queue_limits *t,
 				struct queue_limits *b)
@@ -726,8 +734,8 @@ static bool blk_stack_atomic_writes_head(struct queue_limits *t,
 	return true;
 }
 
-static void blk_stack_atomic_writes_limits(struct queue_limits *t,
-				struct queue_limits *b, sector_t start)
+static bool blk_stack_atomic_writes_hw_limits(struct queue_limits *t,
+				struct queue_limits *b)
 {
 	if (!(b->features & BLK_FEAT_ATOMIC_WRITES))
 		goto unsupported;
@@ -735,9 +743,6 @@ static void blk_stack_atomic_writes_limits(struct queue_limits *t,
 	if (!b->atomic_write_hw_unit_min)
 		goto unsupported;
 
-	if (!blk_atomic_write_start_sect_aligned(start, b))
-		goto unsupported;
-
 	/* UINT_MAX indicates no stacking of bottom devices yet */
 	if (t->atomic_write_hw_max == UINT_MAX) {
 		if (!blk_stack_atomic_writes_head(t, b))
@@ -747,13 +752,19 @@ static void blk_stack_atomic_writes_limits(struct queue_limits *t,
 			goto unsupported;
 	}
 	blk_stack_atomic_writes_chunk_sectors(t);
-	return;
+	return true;
 
 unsupported:
-	t->atomic_write_hw_max = 0;
-	t->atomic_write_hw_unit_max = 0;
-	t->atomic_write_hw_unit_min = 0;
-	t->atomic_write_hw_boundary = 0;
+	blk_clear_atomic_write_limits(t);
+	return false;
+}
+
+static void blk_stack_atomic_writes_limits(struct queue_limits *t,
+				struct queue_limits *b, sector_t start)
+{
+	if (blk_stack_atomic_writes_hw_limits(t, b) &&
+	    !blk_atomic_write_start_sect_aligned(start, b))
+		blk_clear_atomic_write_limits(t);
 }
 
 #define STACK_MIN_NOT_ZERO(t, b, field) \
-- 
2.25.1



More information about the Linux-nvme mailing list