[PATCH] nvme: unregister when pr_register() is given a zero new key
Daejun Park via B4 Relay
devnull+daejun7.park.samsung.com at kernel.org
Wed Oct 28 17:51:24 PDT 2026
From: Daejun Park <daejun7.park at samsung.com>
The block layer PR API defines a zero new_key in pr_register() as
unregistering old_key. nvme_pr_register() sends Replace Reservation
Key with a zero NRKEY instead. The host stays registered with key 0,
and its next registration with another key fails with Reservation
Conflict.
The pNFS SCSI layout client unregisters this way at umount. A later
mount cannot register and sends all I/O through the metadata server.
Send Unregister Reservation Key when new_key is zero.
Fixes: 1d277a637a71 ("NVMe: Add persistent reservation ops")
Cc: stable at vger.kernel.org
Signed-off-by: Daejun Park <daejun7.park at samsung.com>
---
Tested with IOC_PR_REGISTER on an nvmet nvme-loop namespace and on
dm-linear over it. Registering a new key after unregister now works.
A wrong old_key still gets Reservation Conflict.
---
drivers/nvme/host/pr.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/nvme/host/pr.c b/drivers/nvme/host/pr.c
index fe7dbe2648..d8b6ac4d83 100644
--- a/drivers/nvme/host/pr.c
+++ b/drivers/nvme/host/pr.c
@@ -128,8 +128,12 @@ static int nvme_pr_register(struct block_device *bdev, u64 old_key, u64 new_key,
data.crkey = cpu_to_le64(old_key);
data.nrkey = cpu_to_le64(new_key);
- cdw10 = old_key ? NVME_PR_REGISTER_ACT_REPLACE :
- NVME_PR_REGISTER_ACT_REG;
+ if (!new_key)
+ cdw10 = NVME_PR_REGISTER_ACT_UNREG;
+ else if (old_key)
+ cdw10 = NVME_PR_REGISTER_ACT_REPLACE;
+ else
+ cdw10 = NVME_PR_REGISTER_ACT_REG;
cdw10 |= (flags & PR_FL_IGNORE_KEY) ? NVME_PR_IGNORE_KEY : 0;
cdw10 |= NVME_PR_CPTPL_PERSIST;
---
base-commit: 65ba8f34ec886ec72b2c07ddc8cf3d815c32869d
change-id: 20261028-nvme-pr-unreg-24fa60ffe3c3
Best regards,
--
Daejun Park <daejun7.park at samsung.com>
More information about the Linux-nvme
mailing list