[PATCH 2/7] nvmet: bdev: add support of Compare command

Dmitry Bogdanov d.bogdanov at yadro.com
Wed Sep 11 23:42:54 PDT 2024


Add handling of Compare command for block device backend.

Signed-off-by: Dmitry Bogdanov <d.bogdanov at yadro.com>
---
 drivers/nvme/target/io-cmd-bdev.c | 34 ++++++++++++++++++++++++++++---
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c
index 0bda83d0fc3e..0bbe95585dcd 100644
--- a/drivers/nvme/target/io-cmd-bdev.c
+++ b/drivers/nvme/target/io-cmd-bdev.c
@@ -183,8 +183,19 @@ u16 blk_to_nvme_status(struct nvmet_req *req, blk_status_t blk_sts)
 static void nvmet_bio_done(struct bio *bio)
 {
 	struct nvmet_req *req = bio->bi_private;
+	u16 status;
+
+	status = blk_to_nvme_status(req, bio->bi_status);
+
+	if (req->cmd->rw.opcode == nvme_cmd_compare) {
+		if (likely(!status))
+			status = nvmet_compare_sg(req);
+
+		sgl_free(req->sg);
+		req->sg = req->cmp_sg;
+	}
 
-	nvmet_req_complete(req, blk_to_nvme_status(req, bio->bi_status));
+	nvmet_req_complete(req, status);
 	nvmet_req_bio_put(req, bio);
 }
 
@@ -262,14 +273,30 @@ static void nvmet_bdev_execute_rw(struct nvmet_req *req)
 		return;
 	}
 
-	if (req->cmd->rw.opcode == nvme_cmd_write) {
+	switch (req->cmd->rw.opcode) {
+	case nvme_cmd_write:
 		opf = REQ_OP_WRITE | REQ_SYNC | REQ_IDLE;
 		if (req->cmd->rw.control & cpu_to_le16(NVME_RW_FUA))
 			opf |= REQ_FUA;
 		iter_flags = SG_MITER_TO_SG;
-	} else {
+		break;
+	case nvme_cmd_compare:
 		opf = REQ_OP_READ;
 		iter_flags = SG_MITER_FROM_SG;
+
+		req->cmp_sg = req->sg;
+		req->sg = sgl_alloc(nvmet_rw_data_len(req), GFP_KERNEL,
+					&req->sg_cnt);
+
+		if (unlikely(!req->sg || WARN_ON(sg_cnt != req->sg_cnt))) {
+			nvmet_req_complete(req, NVME_SC_INTERNAL);
+			return;
+		}
+		break;
+	default:
+		opf = REQ_OP_READ;
+		iter_flags = SG_MITER_FROM_SG;
+		break;
 	}
 
 	if (is_pci_p2pdma_page(sg_page(req->sg)))
@@ -458,6 +485,7 @@ u16 nvmet_bdev_parse_io_cmd(struct nvmet_req *req)
 	switch (req->cmd->common.opcode) {
 	case nvme_cmd_read:
 	case nvme_cmd_write:
+	case nvme_cmd_compare:
 		req->execute = nvmet_bdev_execute_rw;
 		if (req->sq->ctrl->pi_support && nvmet_ns_has_pi(req->ns))
 			req->metadata_len = nvmet_rw_metadata_len(req);
-- 
2.25.1




More information about the Linux-nvme mailing list