Skip to contentSkip to conversation

NVMe: Persistent Reservation NVMe translations

PATCH New Keith Busch 1 participant 2 messages Mar 23, 2015

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 NVMe: Persistent Reservation NVMe translations

This provides SCSI-to-NVMe translations for persistent reservations.

The ONCS enums are updated to include all the optional commands between the previous last define up to reservation support.

Signed-off-by Keith Busch <keith.busch at intel.com>

---
Tested with sg3-util's sg_persist. I can't seem to get everyone to abandon their old scsi tools and adopt native nvme management. :)

If anyone's interested, I can push my emulator implementing reservations to my qemu tree.

This is done (mostly) in accordance with the translation reference on nvmexpress.org. There is one errata in that translation regarding the TransportID for PR IN's read-full-status. I fixed the driver's implementation to hijack an ieee format, and will circle back with the committee to get an update in the spec at the next meeting.

Anyway, no rush on this one.

 drivers/block/nvme-core.c |    4 +
 drivers/block/nvme-scsi.c |  452 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/nvme.h      |    1 +
 include/uapi/linux/nvme.h |   10 +
 4 files changed, 467 insertions(+)
drivers/block/nvme-core.c +4 -0
index e23be20..ab7c847 100644
@@ -2040,6 +2040,10 @@ static int nvme_revalidate_disk(struct gendisk *disk)
 	ns->lba_shift = id->lbaf[lbaf].ds;
 	ns->ms = le16_to_cpu(id->lbaf[lbaf].ms);
 
+	if (readl(&dev->bar->vs) >= NVME_VS(1, 1))
+		ns->rescap = id->rescap;
+	else
+		ns->rescap = 0;
 	/*
 	 * If identify namespace failed, use default 512 byte block size so
 	 * block layer can use before failing read/write for 0 capacity.
drivers/block/nvme-scsi.c +452 -0

470 lines not on this page · raw message

include/linux/nvme.h +1 -0
index 0adad4a..7c51f8f 100644
@@ -119,6 +119,7 @@ struct nvme_ns {
 	int lba_shift;
 	int ms;
 	int pi_type;
+	u8 rescap;
 	u64 mode_select_num_blocks;
 	u32 mode_select_block_len;
 };
include/uapi/linux/nvme.h +10 -0
index aef9a81..50d28fc 100644
@@ -89,6 +89,9 @@ enum {
 	NVME_CTRL_ONCS_COMPARE			= 1 << 0,
 	NVME_CTRL_ONCS_WRITE_UNCORRECTABLE	= 1 << 1,
 	NVME_CTRL_ONCS_DSM			= 1 << 2,
+	NVME_CTRL_ONCS_WRITE_ZEROS		= 1 << 3,
+	NVME_CTRL_ONCS_SAVE_SET_FEATURES	= 1 << 4,
+	NVME_CTRL_ONCS_RESERVATIONS		= 1 << 5,
 	NVME_CTRL_VWC_PRESENT			= 1 << 0,
 };
 
@@ -146,6 +149,13 @@ enum {
 	NVME_NS_DPS_PI_TYPE1	= 1,
 	NVME_NS_DPS_PI_TYPE2	= 2,
 	NVME_NS_DPS_PI_TYPE3	= 3,
+	NVME_NS_RESCAP_PTPL	= 1 << 0,
+	NVME_NS_RESCAP_WR_EX	= 1 << 1,
+	NVME_NS_RESCAP_EX_AC	= 1 << 2,
+	NVME_NS_RESCAP_WR_EX_RO	= 1 << 3,
+	NVME_NS_RESCAP_EX_AC_RO	= 1 << 4,
+	NVME_NS_RESCAP_WR_EX_AR	= 1 << 5,
+	NVME_NS_RESCAP_EX_AC_AR	= 1 << 6,
 };
 
 struct nvme_smart_log {
Signature · 1 line
1.7.10.4
#1 lore raw

PATCH 1/1 NVMe: Persistent Reservation NVMe translations

drivers/block/nvme-scsi.c static int nvme_trans_unmap(struct nvme_ns *ns, struct sg_io_hdr *hdr, · line 2991

Quoted 4 lines · Keith Busch
drivers/block/nvme-scsi.c +4 -0
+	for (i = 0; i < regctl; i++) {
+		keys->keys[i] = cpu_to_be64(le32_to_cpu(
+					resv_status->regctl_ds[i].rkey));
+	}

Sparse failed me! Should be le64_to_cpu, not 32. Pretty sure that's the only type size bug. I'll let this sit for a few days before spinning a v2.