diff options
| author | Guixin Liu <kanie@linux.alibaba.com> | 2026-09-20 11:34:59 +0800 |
|---|---|---|
| committer | Keith Busch <kbusch@kernel.org> | 2026-10-03 01:52:55 -0700 |
| commit | d99bc5b456fd63be46c8bda20dbf6ede93d2fc11 (patch) | |
| tree | c28e9f785186b99972093a9e163eaa964e3f3823 | |
| parent | 684b413b5483f57c890c171b9400076a0143b918 (diff) | |
| download | linux-next-d99bc5b456fd63be46c8bda20dbf6ede93d2fc11.tar.gz linux-next-d99bc5b456fd63be46c8bda20dbf6ede93d2fc11.zip | |
nvmet: return Invalid Field for invalid NSIDs feature 82h
The Reservation Notification Mask feature (FID 82h) defines its own
status code for namespaces that do not support reservations:
"If a Set Features command or a Get Features command attempts to
access the Reservation Notification Mask on a namespace that does
not support reservations or is invalid, then that command is
aborted with status code of Invalid Field in Command."
-- NVMe Base Specification, section 5.2.26.1.33
The Set Features handler routes the namespace lookup through
nvmet_req_find_ns(), which returns Invalid Namespace or Format for an
unknown NSID. That is the correct status for the generic
namespace-scoped admin commands, but not for this feature: a Set
Features 82h naming a nonexistent NSID is aborted with Invalid
Namespace or Format instead of Invalid Field in Command.
Translate the lookup failure to Invalid Field in Command. The
broadcast NSID, the namespace-without-reservations case and everything
else keep their current behavior.
Fixes: 5a47c2080a73 ("nvmet: support reservation feature")
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Nilay Shroff <nilay@linux.ibm.com>
Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
| -rw-r--r-- | drivers/nvme/target/pr.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/nvme/target/pr.c b/drivers/nvme/target/pr.c index 09d8c63f5680..81f48cb00aee 100644 --- a/drivers/nvme/target/pr.c +++ b/drivers/nvme/target/pr.c @@ -51,6 +51,8 @@ u16 nvmet_set_feat_resv_notif_mask(struct nvmet_req *req, u32 mask) if (nsid != U32_MAX) { status = nvmet_req_find_ns(req); + if (status == (NVME_SC_INVALID_NS | NVME_STATUS_DNR)) + return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; if (status) return status; if (!req->ns->pr.enable) @@ -75,6 +77,8 @@ u16 nvmet_get_feat_resv_notif_mask(struct nvmet_req *req) u16 status; status = nvmet_req_find_ns(req); + if (status == (NVME_SC_INVALID_NS | NVME_STATUS_DNR)) + return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; if (status) return status; |
