]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
block: ensure correct integrity capability propagation in stacked devices
authorAnuj Gupta <anuj20.g@samsung.com>
Wed, 5 Mar 2025 06:30:32 +0000 (12:00 +0530)
committerJens Axboe <axboe@kernel.dk>
Thu, 6 Mar 2025 15:01:37 +0000 (08:01 -0700)
queue_limits_stack_integrity() incorrectly sets
BLK_INTEGRITY_DEVICE_CAPABLE for a DM device even when none of its
underlying devices support integrity. This happens because the flag is
inherited unconditionally. Ensure that integrity capabilities are
correctly propagated only when the underlying devices actually support
integrity.

Reported-by: M Nikhil <nikh1092@linux.ibm.com>
Link: https://lore.kernel.org/linux-block/f6130475-3ccd-45d2-abde-3ccceada0f0a@linux.ibm.com/
Fixes: c6e56cf6b2e7 ("block: move integrity information into queue_limits")
Signed-off-by: Anuj Gupta <anuj20.g@samsung.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20250305063033.1813-2-anuj20.g@samsung.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-settings.c

index 2763a34a9d569f0bd5d9787b068a2027342a4b1b..25fd7793fd9da6b166ef72b0d0d4ef5a8983e344 100644 (file)
@@ -864,36 +864,28 @@ bool queue_limits_stack_integrity(struct queue_limits *t,
        if (!IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY))
                return true;
 
-       if (!ti->tuple_size) {
-               /* inherit the settings from the first underlying device */
-               if (!(ti->flags & BLK_INTEGRITY_STACKED)) {
-                       ti->flags = BLK_INTEGRITY_DEVICE_CAPABLE |
-                               (bi->flags & BLK_INTEGRITY_REF_TAG);
-                       ti->csum_type = bi->csum_type;
-                       ti->tuple_size = bi->tuple_size;
-                       ti->pi_offset = bi->pi_offset;
-                       ti->interval_exp = bi->interval_exp;
-                       ti->tag_size = bi->tag_size;
-                       goto done;
-               }
-               if (!bi->tuple_size)
-                       goto done;
+       if (ti->flags & BLK_INTEGRITY_STACKED) {
+               if (ti->tuple_size != bi->tuple_size)
+                       goto incompatible;
+               if (ti->interval_exp != bi->interval_exp)
+                       goto incompatible;
+               if (ti->tag_size != bi->tag_size)
+                       goto incompatible;
+               if (ti->csum_type != bi->csum_type)
+                       goto incompatible;
+               if ((ti->flags & BLK_INTEGRITY_REF_TAG) !=
+                   (bi->flags & BLK_INTEGRITY_REF_TAG))
+                       goto incompatible;
+       } else {
+               ti->flags = BLK_INTEGRITY_STACKED;
+               ti->flags |= (bi->flags & BLK_INTEGRITY_DEVICE_CAPABLE) |
+                            (bi->flags & BLK_INTEGRITY_REF_TAG);
+               ti->csum_type = bi->csum_type;
+               ti->tuple_size = bi->tuple_size;
+               ti->pi_offset = bi->pi_offset;
+               ti->interval_exp = bi->interval_exp;
+               ti->tag_size = bi->tag_size;
        }
-
-       if (ti->tuple_size != bi->tuple_size)
-               goto incompatible;
-       if (ti->interval_exp != bi->interval_exp)
-               goto incompatible;
-       if (ti->tag_size != bi->tag_size)
-               goto incompatible;
-       if (ti->csum_type != bi->csum_type)
-               goto incompatible;
-       if ((ti->flags & BLK_INTEGRITY_REF_TAG) !=
-           (bi->flags & BLK_INTEGRITY_REF_TAG))
-               goto incompatible;
-
-done:
-       ti->flags |= BLK_INTEGRITY_STACKED;
        return true;
 
 incompatible: