[PATCH] target: Make TFO->check_stop_free return free status

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

 



From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>

This patch converts target_core_fabric_ops->check_stop_free() usage in
transport_cmd_check_stop() and associated fabric module usage to
return '1' when the passed se_cmd has been released directly within
->check_stop_free(), or return '0' when the passed se_cmd has not
been released.

This addresses an issue where transport_cmd_finish_abort() ->
transport_cmd_check_stop_to_fabric() was leaking descriptors during
LUN_RESET for modules using ->check_stop_free(), but not directly
releasing se_cmd in all cases.

Cc: Christoph Hellwig <hch@xxxxxx>
Signed-off-by: Nicholas Bellinger <nab@xxxxxxxxxxxxxxxxxxxxx>
---
 drivers/infiniband/ulp/srpt/ib_srpt.c           |    4 ++--
 drivers/scsi/ibmvscsi/ibmvscsis.c               |    5 +++--
 drivers/target/loopback/tcm_loop.c              |    5 +++--
 drivers/target/target_core_transport.c          |    7 +++++--
 drivers/target/tcm_fc/tcm_fc.h                  |    2 +-
 drivers/target/tcm_fc/tfc_cmd.c                 |    3 ++-
 drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c |    6 ++++--
 drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.h |    2 +-
 include/target/target_core_fabric_ops.h         |    7 +++++--
 9 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index 7892efc..283bc65 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -1707,12 +1707,12 @@ out_err:
 	goto out;
 }
 
-static void srpt_check_stop_free(struct se_cmd *cmd)
+static int srpt_check_stop_free(struct se_cmd *cmd)
 {
 	struct srpt_send_ioctx *ioctx;
 
 	ioctx = container_of(cmd, struct srpt_send_ioctx, cmd);
-	kref_put(&ioctx->kref, srpt_put_send_ioctx_kref);
+	return kref_put(&ioctx->kref, srpt_put_send_ioctx_kref);
 }
 
 /**
diff --git a/drivers/scsi/ibmvscsi/ibmvscsis.c b/drivers/scsi/ibmvscsi/ibmvscsis.c
index 095f8be..85188a5 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsis.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsis.c
@@ -895,11 +895,12 @@ static int tcm_queuecommand(struct ibmvscsis_adapter *adapter,
 	return 0;
 }
 
-static void ibmvscsis_check_stop_free(struct se_cmd *se_cmd)
+static int ibmvscsis_check_stop_free(struct se_cmd *se_cmd)
 {
 	if (se_cmd->se_tmr_req)
-		return;
+		return 0;
 	transport_generic_free_cmd(se_cmd, 0);
+	return 1;
 }
 
 static u64 scsi_lun_to_int(u64 lun)
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index c0a2edc..c097164 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -205,7 +205,7 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd)
 /*
  * Called from struct target_core_fabric_ops->check_stop_free()
  */
-static void tcm_loop_check_stop_free(struct se_cmd *se_cmd)
+static int tcm_loop_check_stop_free(struct se_cmd *se_cmd)
 {
 	/*
 	 * Do not release struct se_cmd's containing a valid TMR
@@ -213,12 +213,13 @@ static void tcm_loop_check_stop_free(struct se_cmd *se_cmd)
 	 * with transport_generic_free_cmd().
 	 */
 	if (se_cmd->se_tmr_req)
-		return;
+		return 0;
 	/*
 	 * Release the struct se_cmd, which will make a callback to release
 	 * struct tcm_loop_cmd * in tcm_loop_deallocate_core_cmd()
 	 */
 	transport_generic_free_cmd(se_cmd, 0);
+	return 1;
 }
 
 static void tcm_loop_release_cmd(struct se_cmd *se_cmd)
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 1821606..d12131c 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -517,13 +517,16 @@ static int transport_cmd_check_stop(
 			 * Some fabric modules like tcm_loop can release
 			 * their internally allocated I/O reference now and
 			 * struct se_cmd now.
+			 *
+			 * Fabric modules are expected to return '1' here if the
+			 * se_cmd being passed is released at this point,
+			 * or zero if not being released.
 			 */
 			if (cmd->se_tfo->check_stop_free != NULL) {
 				spin_unlock_irqrestore(
 					&cmd->t_state_lock, flags);
 
-				cmd->se_tfo->check_stop_free(cmd);
-				return 1;
+				return cmd->se_tfo->check_stop_free(cmd);
 			}
 		}
 		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
diff --git a/drivers/target/tcm_fc/tcm_fc.h b/drivers/target/tcm_fc/tcm_fc.h
index 8279096..26061f0 100644
--- a/drivers/target/tcm_fc/tcm_fc.h
+++ b/drivers/target/tcm_fc/tcm_fc.h
@@ -156,7 +156,7 @@ int ft_lport_notify(struct notifier_block *, unsigned long, void *);
 /*
  * IO methods.
  */
-void ft_check_stop_free(struct se_cmd *);
+int ft_check_stop_free(struct se_cmd *);
 void ft_release_cmd(struct se_cmd *);
 int ft_queue_status(struct se_cmd *);
 int ft_queue_data_in(struct se_cmd *);
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c
index ccb1239..247bfad 100644
--- a/drivers/target/tcm_fc/tfc_cmd.c
+++ b/drivers/target/tcm_fc/tfc_cmd.c
@@ -112,9 +112,10 @@ void ft_release_cmd(struct se_cmd *se_cmd)
 	ft_free_cmd(cmd);
 }
 
-void ft_check_stop_free(struct se_cmd *se_cmd)
+int ft_check_stop_free(struct se_cmd *se_cmd)
 {
 	transport_generic_free_cmd(se_cmd, 0);
+	return 1;
 }
 
 /*
diff --git a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c
index e05cf90..cb97b68 100644
--- a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c
+++ b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c
@@ -417,7 +417,7 @@ void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd)
 /*
  * Called from struct target_core_fabric_ops->check_stop_free() context
  */
-void tcm_qla2xxx_check_stop_free(struct se_cmd *se_cmd)
+int tcm_qla2xxx_check_stop_free(struct se_cmd *se_cmd)
 {
 	struct qla_tgt_cmd *cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
 	struct qla_tgt_mgmt_cmd *mcmd;
@@ -432,7 +432,7 @@ void tcm_qla2xxx_check_stop_free(struct se_cmd *se_cmd)
 		 */
 		transport_generic_free_cmd(se_cmd, 1);
 		qla_tgt_free_mcmd(mcmd);
-		return;
+		return 1;
 	}
 	ha = cmd->sess->vha->hw;
 	/*
@@ -444,6 +444,8 @@ void tcm_qla2xxx_check_stop_free(struct se_cmd *se_cmd)
 	if (atomic_read(&cmd->cmd_free) != 0)
 		complete(&cmd->cmd_stop_free_comp);
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+	return 0;
 }
 
 /*
diff --git a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.h b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.h
index 55e4eeb..ce166ac 100644
--- a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.h
+++ b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.h
@@ -25,7 +25,7 @@ extern struct se_node_acl *tcm_qla2xxx_alloc_fabric_acl(struct se_portal_group *
 extern void tcm_qla2xxx_release_fabric_acl(struct se_portal_group *, struct se_node_acl *);
 extern u32 tcm_qla2xxx_tpg_get_inst_index(struct se_portal_group *);
 extern void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *);
-extern void tcm_qla2xxx_check_stop_free(struct se_cmd *);
+extern int tcm_qla2xxx_check_stop_free(struct se_cmd *);
 extern void tcm_qla2xxx_release_cmd(struct se_cmd *);
 extern int tcm_qla2xxx_shutdown_session(struct se_session *);
 extern void tcm_qla2xxx_close_session(struct se_session *);
diff --git a/include/target/target_core_fabric_ops.h b/include/target/target_core_fabric_ops.h
index 126c675..04c591d 100644
--- a/include/target/target_core_fabric_ops.h
+++ b/include/target/target_core_fabric_ops.h
@@ -46,9 +46,12 @@ struct target_core_fabric_ops {
 	int (*new_cmd_map)(struct se_cmd *);
 	/*
 	 * Optional to release struct se_cmd and fabric dependent allocated
-	 * I/O descriptor in transport_cmd_check_stop()
+	 * I/O descriptor in transport_cmd_check_stop().
+	 *
+	 * Returning 1 will signal a descriptor has been released.
+	 * Returning 0 will signal a descriptor has not been released.
 	 */
-	void (*check_stop_free)(struct se_cmd *);
+	int (*check_stop_free)(struct se_cmd *);
 	void (*release_cmd)(struct se_cmd *);
 	/*
 	 * Called with spin_lock_bh(struct se_portal_group->session_lock held.
-- 
1.7.2.5

--
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