[PATCH 10/11] nvmet: translate placement identifiers of writes to write streams
Guixin Liu
kanie at linux.alibaba.com
Mon Oct 12 19:21:08 PDT 2026
A write command that carries the Data Placement Directive names a
placement identifier in the Directive Specific field. Both sides of
the bridge use identity mapped handles: the write streams of the
backing device map to the placement handles one by one, in the order
the reclaim unit handle status reports them. Translate the placement
identifier to the matching backing write stream on the write path, so
the data lands in the reclaim unit of the backing device that the
host selected. The enable of the namespace has verified that the
backing placement identifiers are identity mapped.
Writes without the directive, and writes with a placement identifier
that is out of range, keep the default stream 0: the spec lets the
controller place such data itself.
Assisted-by: LLM
Signed-off-by: Guixin Liu <kanie at linux.alibaba.com>
---
drivers/nvme/target/io-cmd-bdev.c | 4 ++++
drivers/nvme/target/nvmet.h | 20 ++++++++++++++++++++
2 files changed, 24 insertions(+)
diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c
index f2d9e8901df4e..ff480f9ab9906 100644
--- a/drivers/nvme/target/io-cmd-bdev.c
+++ b/drivers/nvme/target/io-cmd-bdev.c
@@ -300,6 +300,10 @@ static void nvmet_bdev_execute_rw(struct nvmet_req *req)
bio->bi_iter.bi_sector = sector;
bio->bi_private = req;
bio->bi_end_io = nvmet_bio_done;
+ if (req->cmd->rw.opcode == nvme_cmd_write &&
+ nvmet_fdp_enabled(req->ns)) {
+ bio->bi_write_stream = nvmet_fdp_write_stream(req);
+ }
blk_start_plug(&plug);
if (req->metadata_len)
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 5bcc719973a57..af77591053226 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -1005,6 +1005,26 @@ void nvmet_execute_io_mgmt_recv(struct nvmet_req *req);
void nvmet_execute_io_mgmt_send(struct nvmet_req *req);
void nvmet_execute_get_log_page_fdp_configs(struct nvmet_req *req);
void nvmet_fdp_log_forward(struct nvmet_req *req);
+
+/*
+ * Both sides of the bridge use identity mapped handles, so placement
+ * identifier i routes to backing write stream i+1; stream 0, the
+ * default, places the data without a directive.
+ */
+static inline u8 nvmet_fdp_write_stream(struct nvmet_req *req)
+{
+ u16 control = le16_to_cpu(req->cmd->rw.control);
+ u16 pid;
+
+ if ((control & 0xf0) != (NVME_RW_DTYPE_DPLCMT & 0xf0))
+ return 0;
+
+ pid = le32_to_cpu(req->cmd->rw.dsmgmt) >> 16;
+ if (pid >= req->ns->fdp.nruh)
+ return 0;
+
+ return pid + 1;
+}
#else
static inline bool nvmet_fdp_enabled(struct nvmet_ns *ns)
{
--
2.43.7
More information about the Linux-nvme
mailing list