Skip to content

Commit c292a33

Browse files
kelleymhChristoph Hellwig
authored andcommitted
nvme: Fix IOC_PR_CLEAR and IOC_PR_RELEASE ioctls for nvme devices
The IOC_PR_CLEAR and IOC_PR_RELEASE ioctls are non-functional on NVMe devices because the nvme_pr_clear() and nvme_pr_release() functions set the IEKEY field incorrectly. The IEKEY field should be set only when the key is zero (i.e, not specified). The current code does it backwards. Furthermore, the NVMe spec describes the persistent reservation "clear" function as an option on the reservation release command. The current implementation of nvme_pr_clear() erroneously uses the reservation register command. Fix these errors. Note that NVMe version 1.3 and later specify that setting the IEKEY field will return an error of Invalid Field in Command. The fix will set IEKEY when the key is zero, which is appropriate as these ioctls consider a zero key to be "unspecified", and the intention of the spec change is to require a valid key. Tested on a version 1.4 PCI NVMe device in an Azure VM. Fixes: 1673f1f ("nvme: move block_device_operations and ns/ctrl freeing to common code") Fixes: 1d277a6 ("NVMe: Add persistent reservation ops") Signed-off-by: Michael Kelley <mikelley@microsoft.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
1 parent 4c66a32 commit c292a33

1 file changed

Lines changed: 3 additions & 3 deletions

File tree

drivers/nvme/host/core.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2162,14 +2162,14 @@ static int nvme_pr_preempt(struct block_device *bdev, u64 old, u64 new,
21622162

21632163
static int nvme_pr_clear(struct block_device *bdev, u64 key)
21642164
{
2165-
u32 cdw10 = 1 | (key ? 1 << 3 : 0);
2165+
u32 cdw10 = 1 | (key ? 0 : 1 << 3);
21662166

2167-
return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_register);
2167+
return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release);
21682168
}
21692169

21702170
static int nvme_pr_release(struct block_device *bdev, u64 key, enum pr_type type)
21712171
{
2172-
u32 cdw10 = nvme_pr_type(type) << 8 | (key ? 1 << 3 : 0);
2172+
u32 cdw10 = nvme_pr_type(type) << 8 | (key ? 0 : 1 << 3);
21732173

21742174
return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release);
21752175
}

0 commit comments

Comments
 (0)