Hannes Reinecke d7a1c2
From: Christoph Hellwig <hch@lst.de>
Hannes Reinecke d7a1c2
Date: Wed, 23 Oct 2019 10:35:44 -0600
Hannes Reinecke d7a1c2
Subject: [PATCH] nvmet: Remove the data_len field from the nvmet_req struct
Hannes Reinecke d7a1c2
Git-commit: e9061c397839eea34207668bfedce0a6c18c5015
Hannes Reinecke d7a1c2
Patch-mainline: v5.5-rc1
Hannes Reinecke d7a1c2
References: bsc#1169045
Hannes Reinecke d7a1c2
Hannes Reinecke d7a1c2
Instead of storing the expected length and checking it when it's
Hannes Reinecke d7a1c2
executed, just check the length inside the command themselves.
Hannes Reinecke d7a1c2
Hannes Reinecke d7a1c2
A new helper, nvmet_check_data_len() is created to help with this
Hannes Reinecke d7a1c2
check.
Hannes Reinecke d7a1c2
Hannes Reinecke d7a1c2
Signed-off-by: Christoph Hellwig <hch@lst.de>
Hannes Reinecke d7a1c2
[split patch, udpate changelog]
Hannes Reinecke d7a1c2
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Hannes Reinecke d7a1c2
Signed-off-by: Keith Busch <kbusch@kernel.org>
Hannes Reinecke d7a1c2
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Hannes Reinecke d7a1c2
Acked-by: Hannes Reinecke <hare@suse.com>
Hannes Reinecke d7a1c2
---
Hannes Reinecke d7a1c2
 drivers/nvme/target/admin-cmd.c   | 35 ++++++++++++++++++++++++-----------
Hannes Reinecke d7a1c2
 drivers/nvme/target/core.c        | 16 ++++++++++++----
Hannes Reinecke d7a1c2
 drivers/nvme/target/discovery.c   | 18 ++++++++++++------
Hannes Reinecke d7a1c2
 drivers/nvme/target/fabrics-cmd.c | 15 ++++++++++++---
Hannes Reinecke d7a1c2
 drivers/nvme/target/io-cmd-bdev.c | 19 +++++++++++++------
Hannes Reinecke d7a1c2
 drivers/nvme/target/io-cmd-file.c | 19 ++++++++++++-------
Hannes Reinecke d7a1c2
 drivers/nvme/target/nvmet.h       |  3 +--
Hannes Reinecke d7a1c2
 7 files changed, 86 insertions(+), 39 deletions(-)
Hannes Reinecke d7a1c2
Hannes Reinecke d7a1c2
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
Hannes Reinecke d7a1c2
index 3665b45d6515..cd2c3a79f3b5 100644
Hannes Reinecke d7a1c2
--- a/drivers/nvme/target/admin-cmd.c
Hannes Reinecke d7a1c2
+++ b/drivers/nvme/target/admin-cmd.c
Hannes Reinecke d7a1c2
@@ -31,7 +31,7 @@ u64 nvmet_get_log_page_offset(struct nvme_command *cmd)
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
 static void nvmet_execute_get_log_page_noop(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 {
Hannes Reinecke d7a1c2
-	nvmet_req_complete(req, nvmet_zero_sgl(req, 0, req->data_len));
Hannes Reinecke d7a1c2
+	nvmet_req_complete(req, nvmet_zero_sgl(req, 0, req->transfer_len));
Hannes Reinecke d7a1c2
 }
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
 static void nvmet_execute_get_log_page_error(struct nvmet_req *req)
Hannes Reinecke d7a1c2
@@ -134,7 +134,7 @@ static void nvmet_execute_get_log_page_smart(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	u16 status = NVME_SC_INTERNAL;
Hannes Reinecke d7a1c2
 	unsigned long flags;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
-	if (req->data_len != sizeof(*log))
Hannes Reinecke d7a1c2
+	if (req->transfer_len != sizeof(*log))
Hannes Reinecke d7a1c2
 		goto out;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
 	log = kzalloc(sizeof(*log), GFP_KERNEL);
Hannes Reinecke d7a1c2
@@ -196,7 +196,7 @@ static void nvmet_execute_get_log_changed_ns(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	u16 status = NVME_SC_INTERNAL;
Hannes Reinecke d7a1c2
 	size_t len;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
-	if (req->data_len != NVME_MAX_CHANGED_NAMESPACES * sizeof(__le32))
Hannes Reinecke d7a1c2
+	if (req->transfer_len != NVME_MAX_CHANGED_NAMESPACES * sizeof(__le32))
Hannes Reinecke d7a1c2
 		goto out;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
 	mutex_lock(&ctrl->lock);
Hannes Reinecke d7a1c2
@@ -206,7 +206,7 @@ static void nvmet_execute_get_log_changed_ns(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 		len = ctrl->nr_changed_ns * sizeof(__le32);
Hannes Reinecke d7a1c2
 	status = nvmet_copy_to_sgl(req, 0, ctrl->changed_ns_list, len);
Hannes Reinecke d7a1c2
 	if (!status)
Hannes Reinecke d7a1c2
-		status = nvmet_zero_sgl(req, len, req->data_len - len);
Hannes Reinecke d7a1c2
+		status = nvmet_zero_sgl(req, len, req->transfer_len - len);
Hannes Reinecke d7a1c2
 	ctrl->nr_changed_ns = 0;
Hannes Reinecke d7a1c2
 	nvmet_clear_aen_bit(req, NVME_AEN_BIT_NS_ATTR);
Hannes Reinecke d7a1c2
 	mutex_unlock(&ctrl->lock);
Hannes Reinecke d7a1c2
@@ -284,6 +284,9 @@ static void nvmet_execute_get_log_page_ana(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
 static void nvmet_execute_get_log_page(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 {
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, nvmet_get_log_page_len(req->cmd)))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	switch (req->cmd->get_log_page.lid) {
Hannes Reinecke d7a1c2
 	case NVME_LOG_ERROR:
Hannes Reinecke d7a1c2
 		return nvmet_execute_get_log_page_error(req);
Hannes Reinecke d7a1c2
@@ -594,6 +597,9 @@ static void nvmet_execute_identify_desclist(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
 static void nvmet_execute_identify(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 {
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, NVME_IDENTIFY_DATA_SIZE))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	switch (req->cmd->identify.cns) {
Hannes Reinecke d7a1c2
 	case NVME_ID_CNS_NS:
Hannes Reinecke d7a1c2
 		return nvmet_execute_identify_ns(req);
Hannes Reinecke d7a1c2
@@ -620,6 +626,8 @@ static void nvmet_execute_identify(struct nvmet_req *req)
Hannes Reinecke d7a1c2
  */
Hannes Reinecke d7a1c2
 static void nvmet_execute_abort(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 {
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, 0))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
 	nvmet_set_result(req, 1);
Hannes Reinecke d7a1c2
 	nvmet_req_complete(req, 0);
Hannes Reinecke d7a1c2
 }
Hannes Reinecke d7a1c2
@@ -704,6 +712,9 @@ static void nvmet_execute_set_features(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	u32 cdw10 = le32_to_cpu(req->cmd->common.cdw10);
Hannes Reinecke d7a1c2
 	u16 status = 0;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, 0))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	switch (cdw10 & 0xff) {
Hannes Reinecke d7a1c2
 	case NVME_FEAT_NUM_QUEUES:
Hannes Reinecke d7a1c2
 		nvmet_set_result(req,
Hannes Reinecke d7a1c2
@@ -767,6 +778,9 @@ static void nvmet_execute_get_features(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	u32 cdw10 = le32_to_cpu(req->cmd->common.cdw10);
Hannes Reinecke d7a1c2
 	u16 status = 0;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, 0))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	switch (cdw10 & 0xff) {
Hannes Reinecke d7a1c2
 	/*
Hannes Reinecke d7a1c2
 	 * These features are mandatory in the spec, but we don't
Hannes Reinecke d7a1c2
@@ -831,6 +845,9 @@ void nvmet_execute_async_event(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 {
Hannes Reinecke d7a1c2
 	struct nvmet_ctrl *ctrl = req->sq->ctrl;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, 0))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	mutex_lock(&ctrl->lock);
Hannes Reinecke d7a1c2
 	if (ctrl->nr_async_event_cmds >= NVMET_ASYNC_EVENTS) {
Hannes Reinecke d7a1c2
 		mutex_unlock(&ctrl->lock);
Hannes Reinecke d7a1c2
@@ -847,6 +864,9 @@ void nvmet_execute_keep_alive(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 {
Hannes Reinecke d7a1c2
 	struct nvmet_ctrl *ctrl = req->sq->ctrl;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, 0))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	pr_debug("ctrl %d update keep-alive timer for %d secs\n",
Hannes Reinecke d7a1c2
 		ctrl->cntlid, ctrl->kato);
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
@@ -866,31 +886,24 @@ u16 nvmet_parse_admin_cmd(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	switch (cmd->common.opcode) {
Hannes Reinecke d7a1c2
 	case nvme_admin_get_log_page:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_execute_get_log_page;
Hannes Reinecke d7a1c2
-		req->data_len = nvmet_get_log_page_len(cmd);
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	case nvme_admin_identify:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_execute_identify;
Hannes Reinecke d7a1c2
-		req->data_len = NVME_IDENTIFY_DATA_SIZE;
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	case nvme_admin_abort_cmd:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_execute_abort;
Hannes Reinecke d7a1c2
-		req->data_len = 0;
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	case nvme_admin_set_features:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_execute_set_features;
Hannes Reinecke d7a1c2
-		req->data_len = 0;
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	case nvme_admin_get_features:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_execute_get_features;
Hannes Reinecke d7a1c2
-		req->data_len = 0;
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	case nvme_admin_async_event:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_execute_async_event;
Hannes Reinecke d7a1c2
-		req->data_len = 0;
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	case nvme_admin_keep_alive:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_execute_keep_alive;
Hannes Reinecke d7a1c2
-		req->data_len = 0;
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	}
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
Hannes Reinecke d7a1c2
index 6b39cfc6ade1..565def19d593 100644
Hannes Reinecke d7a1c2
--- a/drivers/nvme/target/core.c
Hannes Reinecke d7a1c2
+++ b/drivers/nvme/target/core.c
Hannes Reinecke d7a1c2
@@ -930,13 +930,21 @@ void nvmet_req_uninit(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 }
Hannes Reinecke d7a1c2
 EXPORT_SYMBOL_GPL(nvmet_req_uninit);
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
-void nvmet_req_execute(struct nvmet_req *req)
Hannes Reinecke d7a1c2
+bool nvmet_check_data_len(struct nvmet_req *req, size_t data_len)
Hannes Reinecke d7a1c2
 {
Hannes Reinecke d7a1c2
-	if (unlikely(req->data_len != req->transfer_len)) {
Hannes Reinecke d7a1c2
+	if (unlikely(data_len != req->transfer_len)) {
Hannes Reinecke d7a1c2
 		req->error_loc = offsetof(struct nvme_common_command, dptr);
Hannes Reinecke d7a1c2
 		nvmet_req_complete(req, NVME_SC_SGL_INVALID_DATA | NVME_SC_DNR);
Hannes Reinecke d7a1c2
-	} else
Hannes Reinecke d7a1c2
-		req->execute(req);
Hannes Reinecke d7a1c2
+		return false;
Hannes Reinecke d7a1c2
+	}
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
+	return true;
Hannes Reinecke d7a1c2
+}
Hannes Reinecke d7a1c2
+EXPORT_SYMBOL_GPL(nvmet_check_data_len);
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
+void nvmet_req_execute(struct nvmet_req *req)
Hannes Reinecke d7a1c2
+{
Hannes Reinecke d7a1c2
+	req->execute(req);
Hannes Reinecke d7a1c2
 }
Hannes Reinecke d7a1c2
 EXPORT_SYMBOL_GPL(nvmet_req_execute);
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
diff --git a/drivers/nvme/target/discovery.c b/drivers/nvme/target/discovery.c
Hannes Reinecke d7a1c2
index 825e61e61b0c..7a868c3e8e95 100644
Hannes Reinecke d7a1c2
--- a/drivers/nvme/target/discovery.c
Hannes Reinecke d7a1c2
+++ b/drivers/nvme/target/discovery.c
Hannes Reinecke d7a1c2
@@ -171,6 +171,9 @@ static void nvmet_execute_disc_get_log_page(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	u16 status = 0;
Hannes Reinecke d7a1c2
 	void *buffer;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, data_len))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	if (req->cmd->get_log_page.lid != NVME_LOG_DISC) {
Hannes Reinecke d7a1c2
 		req->error_loc =
Hannes Reinecke d7a1c2
 			offsetof(struct nvme_get_log_page_command, lid);
Hannes Reinecke d7a1c2
@@ -240,6 +243,9 @@ static void nvmet_execute_disc_identify(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	struct nvme_id_ctrl *id;
Hannes Reinecke d7a1c2
 	u16 status = 0;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, NVME_IDENTIFY_DATA_SIZE))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	if (req->cmd->identify.cns != NVME_ID_CNS_CTRL) {
Hannes Reinecke d7a1c2
 		req->error_loc = offsetof(struct nvme_identify, cns);
Hannes Reinecke d7a1c2
 		status = NVME_SC_INVALID_OPCODE | NVME_SC_DNR;
Hannes Reinecke d7a1c2
@@ -286,6 +292,9 @@ static void nvmet_execute_disc_set_features(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	u32 cdw10 = le32_to_cpu(req->cmd->common.cdw10);
Hannes Reinecke d7a1c2
 	u16 stat;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, 0))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	switch (cdw10 & 0xff) {
Hannes Reinecke d7a1c2
 	case NVME_FEAT_KATO:
Hannes Reinecke d7a1c2
 		stat = nvmet_set_feat_kato(req);
Hannes Reinecke d7a1c2
@@ -309,6 +318,9 @@ static void nvmet_execute_disc_get_features(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	u32 cdw10 = le32_to_cpu(req->cmd->common.cdw10);
Hannes Reinecke d7a1c2
 	u16 stat = 0;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, 0))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	switch (cdw10 & 0xff) {
Hannes Reinecke d7a1c2
 	case NVME_FEAT_KATO:
Hannes Reinecke d7a1c2
 		nvmet_get_feat_kato(req);
Hannes Reinecke d7a1c2
@@ -341,26 +353,20 @@ u16 nvmet_parse_discovery_cmd(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	switch (cmd->common.opcode) {
Hannes Reinecke d7a1c2
 	case nvme_admin_set_features:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_execute_disc_set_features;
Hannes Reinecke d7a1c2
-		req->data_len = 0;
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	case nvme_admin_get_features:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_execute_disc_get_features;
Hannes Reinecke d7a1c2
-		req->data_len = 0;
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	case nvme_admin_async_event:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_execute_async_event;
Hannes Reinecke d7a1c2
-		req->data_len = 0;
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	case nvme_admin_keep_alive:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_execute_keep_alive;
Hannes Reinecke d7a1c2
-		req->data_len = 0;
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	case nvme_admin_get_log_page:
Hannes Reinecke d7a1c2
-		req->data_len = nvmet_get_log_page_len(cmd);
Hannes Reinecke d7a1c2
 		req->execute = nvmet_execute_disc_get_log_page;
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	case nvme_admin_identify:
Hannes Reinecke d7a1c2
-		req->data_len = NVME_IDENTIFY_DATA_SIZE;
Hannes Reinecke d7a1c2
 		req->execute = nvmet_execute_disc_identify;
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	default:
Hannes Reinecke d7a1c2
diff --git a/drivers/nvme/target/fabrics-cmd.c b/drivers/nvme/target/fabrics-cmd.c
Hannes Reinecke d7a1c2
index d16b55ffe79f..f7297473d9eb 100644
Hannes Reinecke d7a1c2
--- a/drivers/nvme/target/fabrics-cmd.c
Hannes Reinecke d7a1c2
+++ b/drivers/nvme/target/fabrics-cmd.c
Hannes Reinecke d7a1c2
@@ -12,6 +12,9 @@ static void nvmet_execute_prop_set(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	u64 val = le64_to_cpu(req->cmd->prop_set.value);
Hannes Reinecke d7a1c2
 	u16 status = 0;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, 0))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	if (req->cmd->prop_set.attrib & 1) {
Hannes Reinecke d7a1c2
 		req->error_loc =
Hannes Reinecke d7a1c2
 			offsetof(struct nvmf_property_set_command, attrib);
Hannes Reinecke d7a1c2
@@ -38,6 +41,9 @@ static void nvmet_execute_prop_get(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	u16 status = 0;
Hannes Reinecke d7a1c2
 	u64 val = 0;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, 0))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	if (req->cmd->prop_get.attrib & 1) {
Hannes Reinecke d7a1c2
 		switch (le32_to_cpu(req->cmd->prop_get.offset)) {
Hannes Reinecke d7a1c2
 		case NVME_REG_CAP:
Hannes Reinecke d7a1c2
@@ -82,11 +88,9 @@ u16 nvmet_parse_fabrics_cmd(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
 	switch (cmd->fabrics.fctype) {
Hannes Reinecke d7a1c2
 	case nvme_fabrics_type_property_set:
Hannes Reinecke d7a1c2
-		req->data_len = 0;
Hannes Reinecke d7a1c2
 		req->execute = nvmet_execute_prop_set;
Hannes Reinecke d7a1c2
 		break;
Hannes Reinecke d7a1c2
 	case nvme_fabrics_type_property_get:
Hannes Reinecke d7a1c2
-		req->data_len = 0;
Hannes Reinecke d7a1c2
 		req->execute = nvmet_execute_prop_get;
Hannes Reinecke d7a1c2
 		break;
Hannes Reinecke d7a1c2
 	default:
Hannes Reinecke d7a1c2
@@ -147,6 +151,9 @@ static void nvmet_execute_admin_connect(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	struct nvmet_ctrl *ctrl = NULL;
Hannes Reinecke d7a1c2
 	u16 status = 0;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, sizeof(struct nvmf_connect_data)))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	d = kmalloc(sizeof(*d), GFP_KERNEL);
Hannes Reinecke d7a1c2
 	if (!d) {
Hannes Reinecke d7a1c2
 		status = NVME_SC_INTERNAL;
Hannes Reinecke d7a1c2
@@ -211,6 +218,9 @@ static void nvmet_execute_io_connect(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	u16 qid = le16_to_cpu(c->qid);
Hannes Reinecke d7a1c2
 	u16 status = 0;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, sizeof(struct nvmf_connect_data)))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	d = kmalloc(sizeof(*d), GFP_KERNEL);
Hannes Reinecke d7a1c2
 	if (!d) {
Hannes Reinecke d7a1c2
 		status = NVME_SC_INTERNAL;
Hannes Reinecke d7a1c2
@@ -281,7 +291,6 @@ u16 nvmet_parse_connect_cmd(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 		return NVME_SC_INVALID_OPCODE | NVME_SC_DNR;
Hannes Reinecke d7a1c2
 	}
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
-	req->data_len = sizeof(struct nvmf_connect_data);
Hannes Reinecke d7a1c2
 	if (cmd->connect.qid == 0)
Hannes Reinecke d7a1c2
 		req->execute = nvmet_execute_admin_connect;
Hannes Reinecke d7a1c2
 	else
Hannes Reinecke d7a1c2
diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c
Hannes Reinecke d7a1c2
index f2618dc2ef3a..04a9cd2a2604 100644
Hannes Reinecke d7a1c2
--- a/drivers/nvme/target/io-cmd-bdev.c
Hannes Reinecke d7a1c2
+++ b/drivers/nvme/target/io-cmd-bdev.c
Hannes Reinecke d7a1c2
@@ -150,6 +150,9 @@ static void nvmet_bdev_execute_rw(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	sector_t sector;
Hannes Reinecke d7a1c2
 	int op, op_flags = 0, i;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, nvmet_rw_len(req)))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	if (!req->sg_cnt) {
Hannes Reinecke d7a1c2
 		nvmet_req_complete(req, 0);
Hannes Reinecke d7a1c2
 		return;
Hannes Reinecke d7a1c2
@@ -170,7 +173,7 @@ static void nvmet_bdev_execute_rw(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	sector = le64_to_cpu(req->cmd->rw.slba);
Hannes Reinecke d7a1c2
 	sector <<= (req->ns->blksize_shift - 9);
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
-	if (req->data_len <= NVMET_MAX_INLINE_DATA_LEN) {
Hannes Reinecke d7a1c2
+	if (req->transfer_len <= NVMET_MAX_INLINE_DATA_LEN) {
Hannes Reinecke d7a1c2
 		bio = &req->b.inline_bio;
Hannes Reinecke d7a1c2
 		bio_init(bio, req->inline_bvec, ARRAY_SIZE(req->inline_bvec));
Hannes Reinecke d7a1c2
 	} else {
Hannes Reinecke d7a1c2
@@ -207,6 +210,9 @@ static void nvmet_bdev_execute_flush(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 {
Hannes Reinecke d7a1c2
 	struct bio *bio = &req->b.inline_bio;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, 0))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	bio_init(bio, req->inline_bvec, ARRAY_SIZE(req->inline_bvec));
Hannes Reinecke d7a1c2
 	bio_set_dev(bio, req->ns->bdev);
Hannes Reinecke d7a1c2
 	bio->bi_private = req;
Hannes Reinecke d7a1c2
@@ -272,6 +278,9 @@ static void nvmet_bdev_execute_discard(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
 static void nvmet_bdev_execute_dsm(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 {
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, nvmet_dsm_len(req)))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	switch (le32_to_cpu(req->cmd->dsm.attributes)) {
Hannes Reinecke d7a1c2
 	case NVME_DSMGMT_AD:
Hannes Reinecke d7a1c2
 		nvmet_bdev_execute_discard(req);
Hannes Reinecke d7a1c2
@@ -293,6 +302,9 @@ static void nvmet_bdev_execute_write_zeroes(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	sector_t nr_sector;
Hannes Reinecke d7a1c2
 	int ret;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, 0))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	sector = le64_to_cpu(write_zeroes->slba) <<
Hannes Reinecke d7a1c2
 		(req->ns->blksize_shift - 9);
Hannes Reinecke d7a1c2
 	nr_sector = (((sector_t)le16_to_cpu(write_zeroes->length) + 1) <<
Hannes Reinecke d7a1c2
@@ -317,20 +329,15 @@ u16 nvmet_bdev_parse_io_cmd(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	case nvme_cmd_read:
Hannes Reinecke d7a1c2
 	case nvme_cmd_write:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_bdev_execute_rw;
Hannes Reinecke d7a1c2
-		req->data_len = nvmet_rw_len(req);
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	case nvme_cmd_flush:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_bdev_execute_flush;
Hannes Reinecke d7a1c2
-		req->data_len = 0;
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	case nvme_cmd_dsm:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_bdev_execute_dsm;
Hannes Reinecke d7a1c2
-		req->data_len = (le32_to_cpu(cmd->dsm.nr) + 1) *
Hannes Reinecke d7a1c2
-			sizeof(struct nvme_dsm_range);
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	case nvme_cmd_write_zeroes:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_bdev_execute_write_zeroes;
Hannes Reinecke d7a1c2
-		req->data_len = 0;
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	default:
Hannes Reinecke d7a1c2
 		pr_err("unhandled cmd %d on qid %d\n", cmd->common.opcode,
Hannes Reinecke d7a1c2
diff --git a/drivers/nvme/target/io-cmd-file.c b/drivers/nvme/target/io-cmd-file.c
Hannes Reinecke d7a1c2
index 7481556da6e6..caebfce06605 100644
Hannes Reinecke d7a1c2
--- a/drivers/nvme/target/io-cmd-file.c
Hannes Reinecke d7a1c2
+++ b/drivers/nvme/target/io-cmd-file.c
Hannes Reinecke d7a1c2
@@ -126,7 +126,7 @@ static void nvmet_file_io_done(struct kiocb *iocb, long ret, long ret2)
Hannes Reinecke d7a1c2
 			mempool_free(req->f.bvec, req->ns->bvec_pool);
Hannes Reinecke d7a1c2
 	}
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
-	if (unlikely(ret != req->data_len))
Hannes Reinecke d7a1c2
+	if (unlikely(ret != req->transfer_len))
Hannes Reinecke d7a1c2
 		status = errno_to_nvme_status(req, ret);
Hannes Reinecke d7a1c2
 	nvmet_req_complete(req, status);
Hannes Reinecke d7a1c2
 }
Hannes Reinecke d7a1c2
@@ -146,7 +146,7 @@ static bool nvmet_file_execute_io(struct nvmet_req *req, int ki_flags)
Hannes Reinecke d7a1c2
 		is_sync = true;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
 	pos = le64_to_cpu(req->cmd->rw.slba) << req->ns->blksize_shift;
Hannes Reinecke d7a1c2
-	if (unlikely(pos + req->data_len > req->ns->size)) {
Hannes Reinecke d7a1c2
+	if (unlikely(pos + req->transfer_len > req->ns->size)) {
Hannes Reinecke d7a1c2
 		nvmet_req_complete(req, errno_to_nvme_status(req, -ENOSPC));
Hannes Reinecke d7a1c2
 		return true;
Hannes Reinecke d7a1c2
 	}
Hannes Reinecke d7a1c2
@@ -173,7 +173,7 @@ static bool nvmet_file_execute_io(struct nvmet_req *req, int ki_flags)
Hannes Reinecke d7a1c2
 		nr_bvec--;
Hannes Reinecke d7a1c2
 	}
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
-	if (WARN_ON_ONCE(total_len != req->data_len)) {
Hannes Reinecke d7a1c2
+	if (WARN_ON_ONCE(total_len != req->transfer_len)) {
Hannes Reinecke d7a1c2
 		ret = -EIO;
Hannes Reinecke d7a1c2
 		goto complete;
Hannes Reinecke d7a1c2
 	}
Hannes Reinecke d7a1c2
@@ -232,6 +232,9 @@ static void nvmet_file_execute_rw(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 {
Hannes Reinecke d7a1c2
 	ssize_t nr_bvec = req->sg_cnt;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, nvmet_rw_len(req)))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
+
Hannes Reinecke d7a1c2
 	if (!req->sg_cnt || !nr_bvec) {
Hannes Reinecke d7a1c2
 		nvmet_req_complete(req, 0);
Hannes Reinecke d7a1c2
 		return;
Hannes Reinecke d7a1c2
@@ -273,6 +276,8 @@ static void nvmet_file_flush_work(struct work_struct *w)
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
 static void nvmet_file_execute_flush(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 {
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, 0))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
 	INIT_WORK(&req->f.work, nvmet_file_flush_work);
Hannes Reinecke d7a1c2
 	schedule_work(&req->f.work);
Hannes Reinecke d7a1c2
 }
Hannes Reinecke d7a1c2
@@ -331,6 +336,8 @@ static void nvmet_file_dsm_work(struct work_struct *w)
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
 static void nvmet_file_execute_dsm(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 {
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, nvmet_dsm_len(req)))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
 	INIT_WORK(&req->f.work, nvmet_file_dsm_work);
Hannes Reinecke d7a1c2
 	schedule_work(&req->f.work);
Hannes Reinecke d7a1c2
 }
Hannes Reinecke d7a1c2
@@ -359,6 +366,8 @@ static void nvmet_file_write_zeroes_work(struct work_struct *w)
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
 static void nvmet_file_execute_write_zeroes(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 {
Hannes Reinecke d7a1c2
+	if (!nvmet_check_data_len(req, 0))
Hannes Reinecke d7a1c2
+		return;
Hannes Reinecke d7a1c2
 	INIT_WORK(&req->f.work, nvmet_file_write_zeroes_work);
Hannes Reinecke d7a1c2
 	schedule_work(&req->f.work);
Hannes Reinecke d7a1c2
 }
Hannes Reinecke d7a1c2
@@ -371,19 +380,15 @@ u16 nvmet_file_parse_io_cmd(struct nvmet_req *req)
Hannes Reinecke d7a1c2
 	case nvme_cmd_read:
Hannes Reinecke d7a1c2
 	case nvme_cmd_write:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_file_execute_rw;
Hannes Reinecke d7a1c2
-		req->data_len = nvmet_rw_len(req);
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	case nvme_cmd_flush:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_file_execute_flush;
Hannes Reinecke d7a1c2
-		req->data_len = 0;
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	case nvme_cmd_dsm:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_file_execute_dsm;
Hannes Reinecke d7a1c2
-		req->data_len = nvmet_dsm_len(req);
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	case nvme_cmd_write_zeroes:
Hannes Reinecke d7a1c2
 		req->execute = nvmet_file_execute_write_zeroes;
Hannes Reinecke d7a1c2
-		req->data_len = 0;
Hannes Reinecke d7a1c2
 		return 0;
Hannes Reinecke d7a1c2
 	default:
Hannes Reinecke d7a1c2
 		pr_err("unhandled cmd for file ns %d on qid %d\n",
Hannes Reinecke d7a1c2
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
Hannes Reinecke d7a1c2
index 6ccf2d098d9f..ff55f1005b35 100644
Hannes Reinecke d7a1c2
--- a/drivers/nvme/target/nvmet.h
Hannes Reinecke d7a1c2
+++ b/drivers/nvme/target/nvmet.h
Hannes Reinecke d7a1c2
@@ -304,8 +304,6 @@ struct nvmet_req {
Hannes Reinecke d7a1c2
 		} f;
Hannes Reinecke d7a1c2
 	};
Hannes Reinecke d7a1c2
 	int			sg_cnt;
Hannes Reinecke d7a1c2
-	/* data length as parsed from the command: */
Hannes Reinecke d7a1c2
-	size_t			data_len;
Hannes Reinecke d7a1c2
 	/* data length as parsed from the SGL descriptor: */
Hannes Reinecke d7a1c2
 	size_t			transfer_len;
Hannes Reinecke d7a1c2
 
Hannes Reinecke d7a1c2
@@ -375,6 +373,7 @@ u16 nvmet_parse_fabrics_cmd(struct nvmet_req *req);
Hannes Reinecke d7a1c2
 bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq,
Hannes Reinecke d7a1c2
 		struct nvmet_sq *sq, const struct nvmet_fabrics_ops *ops);
Hannes Reinecke d7a1c2
 void nvmet_req_uninit(struct nvmet_req *req);
Hannes Reinecke d7a1c2
+bool nvmet_check_data_len(struct nvmet_req *req, size_t data_len);
Hannes Reinecke d7a1c2
 void nvmet_req_execute(struct nvmet_req *req);
Hannes Reinecke d7a1c2
 void nvmet_req_complete(struct nvmet_req *req, u16 status);
Hannes Reinecke d7a1c2
 int nvmet_req_alloc_sgl(struct nvmet_req *req);
Hannes Reinecke d7a1c2
-- 
Hannes Reinecke d7a1c2
2.16.4
Hannes Reinecke d7a1c2