[PATCH 5/6] target/iscsi: Introduce iscsit_get_cmd() and iscsit_put_cmd()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Keep track in .refcnt of whether or not target_put_sess_cmd() has
already been called.

Signed-off-by: Bart Van Assche <bart.vanassche@xxxxxxxxxxx>
---
 drivers/target/iscsi/cxgbit/cxgbit_target.c  |  2 +-
 drivers/target/iscsi/iscsi_target.c          | 16 ++++++-------
 drivers/target/iscsi/iscsi_target_configfs.c |  4 +++-
 drivers/target/iscsi/iscsi_target_util.c     | 35 +++++++++++++++++++++++++++-
 include/target/iscsi/iscsi_target_core.h     |  1 +
 include/target/iscsi/iscsi_transport.h       |  2 ++
 6 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/drivers/target/iscsi/cxgbit/cxgbit_target.c b/drivers/target/iscsi/cxgbit/cxgbit_target.c
index bdcc8b4c522a..528a25e6cfbd 100644
--- a/drivers/target/iscsi/cxgbit/cxgbit_target.c
+++ b/drivers/target/iscsi/cxgbit/cxgbit_target.c
@@ -956,7 +956,7 @@ cxgbit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr,
 			return -1;
 
 		if (cmd->sense_reason || cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
-			target_put_sess_cmd(&cmd->se_cmd);
+			iscsit_put_cmd(cmd);
 			return 0;
 		} else if (cmd->unsolicited_data) {
 			iscsit_set_unsoliticed_dataout(cmd);
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 73d8eaa0973b..de6b2e430d1a 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -872,8 +872,8 @@ static int iscsit_add_reject_from_cmd(
 	 * scsit_setup_scsi_cmd()
 	 */
 	if (cmd->se_cmd.se_tfo != NULL) {
-		pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n");
-		target_put_sess_cmd(&cmd->se_cmd);
+		pr_debug("iscsi reject: calling iscsit_put_cmd() >>>>>>\n");
+		iscsit_put_cmd(cmd);
 	}
 	return -1;
 }
@@ -1167,7 +1167,7 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
 		hdr->cmdsn, be32_to_cpu(hdr->data_length), payload_length,
 		conn->cid);
 
-	target_get_sess_cmd(&cmd->se_cmd, true);
+	iscsit_get_cmd(cmd);
 
 	cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd,
 						     scsilun_to_int(&hdr->lun));
@@ -1235,7 +1235,7 @@ int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
 		if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
 			return -1;
 		else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
-			target_put_sess_cmd(&cmd->se_cmd);
+			iscsit_put_cmd(cmd);
 			return 0;
 		}
 	}
@@ -1251,7 +1251,7 @@ int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
 		if (!cmd->sense_reason)
 			return 0;
 
-		target_put_sess_cmd(&cmd->se_cmd);
+		iscsit_put_cmd(cmd);
 		return 0;
 	}
 
@@ -1308,7 +1308,7 @@ iscsit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr,
 
 			rc = iscsit_dump_data_payload(cmd->conn,
 						      cmd->first_burst_len, 1);
-			target_put_sess_cmd(&cmd->se_cmd);
+			iscsit_put_cmd(cmd);
 			return rc;
 		} else if (cmd->unsolicited_data)
 			iscsit_set_unsoliticed_dataout(cmd);
@@ -2015,7 +2015,7 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
 				      conn->sess->se_sess, 0, DMA_NONE,
 				      TCM_SIMPLE_TAG, cmd->sense_buffer + 2);
 
-		target_get_sess_cmd(&cmd->se_cmd, true);
+		iscsit_get_cmd(cmd);
 		sess_ref = true;
 		tcm_function = iscsit_convert_tmf(function);
 		if (tcm_function == TMR_UNKNOWN) {
@@ -2134,7 +2134,7 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
 	 */
 	if (sess_ref) {
 		pr_debug("Handle TMR, using sess_ref=true check\n");
-		target_put_sess_cmd(&cmd->se_cmd);
+		iscsit_put_cmd(cmd);
 	}
 
 	iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
index bf40f03755dd..39a7294dfac7 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -1559,7 +1559,9 @@ static void lio_set_default_node_attributes(struct se_node_acl *se_acl)
 
 static int lio_check_stop_free(struct se_cmd *se_cmd)
 {
-	return target_put_sess_cmd(se_cmd);
+	struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
+
+	return iscsit_put_cmd(cmd);
 }
 
 static void lio_release_cmd(struct se_cmd *se_cmd)
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c
index 139746b3b189..1cacfe1003e3 100644
--- a/drivers/target/iscsi/iscsi_target_util.c
+++ b/drivers/target/iscsi/iscsi_target_util.c
@@ -688,6 +688,39 @@ void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn)
 	spin_unlock_bh(&conn->response_queue_lock);
 }
 
+/**
+ * iscsit_get_cmd - add @cmd to the list of active commands
+ * @cmd: iSCSI command.
+ */
+int iscsit_get_cmd(struct iscsi_cmd *cmd)
+{
+	long refcnt = atomic_read(&cmd->refcnt);
+	int ret;
+
+	WARN_ONCE(refcnt != 0, "refcnt = %ld\n", refcnt);
+	ret = target_get_sess_cmd(&cmd->se_cmd, true);
+	if (ret)
+		return ret;
+	atomic_inc(&cmd->refcnt);
+	return ret;
+}
+
+/**
+ * iscsit_put_cmd() - decrease the reference count of @cmd
+ * @cmd: iSCSI command.
+ *
+ * Note: this function must be called only once per command.
+ */
+int iscsit_put_cmd(struct iscsi_cmd *cmd)
+{
+	long refcnt = atomic_read(&cmd->refcnt);
+
+	WARN_ONCE(refcnt <= 0, "refcnt = %ld\n", refcnt);
+	atomic_dec(&cmd->refcnt);
+	return target_put_sess_cmd(&cmd->se_cmd);
+}
+EXPORT_SYMBOL(iscsit_put_cmd);
+
 void iscsit_release_cmd(struct iscsi_cmd *cmd)
 {
 	struct iscsi_session *sess;
@@ -744,7 +777,7 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown)
 		rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown);
 		if (!rc && shutdown && se_cmd && se_cmd->se_sess) {
 			__iscsit_free_cmd(cmd, shutdown);
-			target_put_sess_cmd(se_cmd);
+			iscsit_put_cmd(cmd);
 		}
 	} else {
 		iscsit_release_cmd(cmd);
diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h
index 275581d483dd..83afb5c80fcc 100644
--- a/include/target/iscsi/iscsi_target_core.h
+++ b/include/target/iscsi/iscsi_target_core.h
@@ -349,6 +349,7 @@ struct iscsi_r2t {
 } ____cacheline_aligned;
 
 struct iscsi_cmd {
+	atomic_t		refcnt;
 	enum iscsi_timer_flags_table dataout_timer_flags;
 	/* DataOUT timeout retries */
 	u8			dataout_timeout_retries;
diff --git a/include/target/iscsi/iscsi_transport.h b/include/target/iscsi/iscsi_transport.h
index ff1a4f4cd66d..dd4aa931b14e 100644
--- a/include/target/iscsi/iscsi_transport.h
+++ b/include/target/iscsi/iscsi_transport.h
@@ -125,6 +125,8 @@ extern int iscsit_tmr_post_handler(struct iscsi_cmd *, struct iscsi_conn *);
 extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, int);
 extern int iscsit_sequence_cmd(struct iscsi_conn *, struct iscsi_cmd *,
 			       unsigned char *, __be32);
+extern int iscsit_get_cmd(struct iscsi_cmd *cmd);
+extern int iscsit_put_cmd(struct iscsi_cmd *cmd);
 extern void iscsit_release_cmd(struct iscsi_cmd *);
 extern void iscsit_free_cmd(struct iscsi_cmd *, bool);
 extern void iscsit_add_cmd_to_immediate_queue(struct iscsi_cmd *,
-- 
2.12.0

--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux