nvmet: don't truncate the length of big discards

nvmet_bdev_execute_discard() shifts the 32-bit nlb of a DSM range into
sectors before widening it to sector_t, so on a 4k namespace the top
bits are lost. A 3 TiB range discards 1 TiB, a 2 TiB range discards
nothing, and both complete with success. The target announces no DMRSL,
and hosts other than Linux (and nvme dsm passthrough) do send ranges
that big.

Widen before the shift.

Fixes: a07b4970f4 ("nvmet: add a generic NVMe target")
Cc: Christoph Hellwig <hch@lst.de>
Cc: Sagi Grimberg <sagi@grimberg.me>
Cc: Chaitanya Kulkarni <kch@nvidia.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Keith Busch <kbusch@kernel.org>
This commit is contained in:
Josef Bacik 2026-10-28 10:41:48 -06:00 committed by Keith Busch
parent 799203afd2
commit 424bd0e98c

View File

@ -390,7 +390,8 @@ static void nvmet_bdev_execute_discard(struct nvmet_req *req)
if (status)
break;
nr_sects = le32_to_cpu(range.nlb) << (ns->blksize_shift - 9);
nr_sects = (sector_t)le32_to_cpu(range.nlb) <<
(ns->blksize_shift - 9);
__blkdev_issue_discard(ns->bdev,
nvmet_lba_to_sect(ns, range.slba), nr_sects,
GFP_KERNEL, &bio);