Commit 677e332e authored by Anuj Gupta's avatar Anuj Gupta Committed by Jens Axboe
Browse files

block: ensure correct integrity capability propagation in stacked devices



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: default avatarM Nikhil <nikh1092@linux.ibm.com>
Link: https://lore.kernel.org/linux-block/f6130475-3ccd-45d2-abde-3ccceada0f0a@linux.ibm.com/


Fixes: c6e56cf6 ("block: move integrity information into queue_limits")
Signed-off-by: default avatarAnuj Gupta <anuj20.g@samsung.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20250305063033.1813-2-anuj20.g@samsung.com


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 6cc477c3
Loading
Loading
Loading
Loading
+21 −29
Original line number Diff line number Diff line
@@ -864,22 +864,7 @@ 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)
@@ -891,9 +876,16 @@ bool queue_limits_stack_integrity(struct queue_limits *t,
		if ((ti->flags & BLK_INTEGRITY_REF_TAG) !=
		    (bi->flags & BLK_INTEGRITY_REF_TAG))
			goto incompatible;

done:
	ti->flags |= BLK_INTEGRITY_STACKED;
	} 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;
	}
	return true;

incompatible: