aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2013-05-31 03:46:11 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2013-05-31 04:21:23 -0400
commitd5ddad4168348337d98d6b8f156a3892de444411 (patch)
tree8d9151a21c95709ccc0b58cd60a61beba8248459
parentcea4dcfdad926a27a18e188720efe0f2c9403456 (diff)
target: Propigate up ->cmd_kref put return via transport_generic_free_cmd
Go ahead and propigate up the ->cmd_kref put return value from target_put_sess_cmd() -> transport_release_cmd() -> transport_put_cmd() -> transport_generic_free_cmd(). This is useful for certain fabrics when determining the active I/O shutdown case with SCF_ACK_KREF where a final target_put_sess_cmd() is still required by the caller. Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/target/target_core_transport.c28
-rw-r--r--include/target/target_core_fabric.h2
2 files changed, 16 insertions, 14 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index bbca144821c5..21e315874a54 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -65,7 +65,7 @@ static void transport_complete_task_attr(struct se_cmd *cmd);
65static void transport_handle_queue_full(struct se_cmd *cmd, 65static void transport_handle_queue_full(struct se_cmd *cmd,
66 struct se_device *dev); 66 struct se_device *dev);
67static int transport_generic_get_mem(struct se_cmd *cmd); 67static int transport_generic_get_mem(struct se_cmd *cmd);
68static void transport_put_cmd(struct se_cmd *cmd); 68static int transport_put_cmd(struct se_cmd *cmd);
69static void target_complete_ok_work(struct work_struct *work); 69static void target_complete_ok_work(struct work_struct *work);
70 70
71int init_se_kmem_caches(void) 71int init_se_kmem_caches(void)
@@ -1944,7 +1944,7 @@ static inline void transport_free_pages(struct se_cmd *cmd)
1944 * This routine unconditionally frees a command, and reference counting 1944 * This routine unconditionally frees a command, and reference counting
1945 * or list removal must be done in the caller. 1945 * or list removal must be done in the caller.
1946 */ 1946 */
1947static void transport_release_cmd(struct se_cmd *cmd) 1947static int transport_release_cmd(struct se_cmd *cmd)
1948{ 1948{
1949 BUG_ON(!cmd->se_tfo); 1949 BUG_ON(!cmd->se_tfo);
1950 1950
@@ -1956,11 +1956,11 @@ static void transport_release_cmd(struct se_cmd *cmd)
1956 * If this cmd has been setup with target_get_sess_cmd(), drop 1956 * If this cmd has been setup with target_get_sess_cmd(), drop
1957 * the kref and call ->release_cmd() in kref callback. 1957 * the kref and call ->release_cmd() in kref callback.
1958 */ 1958 */
1959 if (cmd->check_release != 0) { 1959 if (cmd->check_release != 0)
1960 target_put_sess_cmd(cmd->se_sess, cmd); 1960 return target_put_sess_cmd(cmd->se_sess, cmd);
1961 return; 1961
1962 }
1963 cmd->se_tfo->release_cmd(cmd); 1962 cmd->se_tfo->release_cmd(cmd);
1963 return 1;
1964} 1964}
1965 1965
1966/** 1966/**
@@ -1969,7 +1969,7 @@ static void transport_release_cmd(struct se_cmd *cmd)
1969 * 1969 *
1970 * This routine releases our reference to the command and frees it if possible. 1970 * This routine releases our reference to the command and frees it if possible.
1971 */ 1971 */
1972static void transport_put_cmd(struct se_cmd *cmd) 1972static int transport_put_cmd(struct se_cmd *cmd)
1973{ 1973{
1974 unsigned long flags; 1974 unsigned long flags;
1975 1975
@@ -1977,7 +1977,7 @@ static void transport_put_cmd(struct se_cmd *cmd)
1977 if (atomic_read(&cmd->t_fe_count) && 1977 if (atomic_read(&cmd->t_fe_count) &&
1978 !atomic_dec_and_test(&cmd->t_fe_count)) { 1978 !atomic_dec_and_test(&cmd->t_fe_count)) {
1979 spin_unlock_irqrestore(&cmd->t_state_lock, flags); 1979 spin_unlock_irqrestore(&cmd->t_state_lock, flags);
1980 return; 1980 return 0;
1981 } 1981 }
1982 1982
1983 if (cmd->transport_state & CMD_T_DEV_ACTIVE) { 1983 if (cmd->transport_state & CMD_T_DEV_ACTIVE) {
@@ -1987,8 +1987,7 @@ static void transport_put_cmd(struct se_cmd *cmd)
1987 spin_unlock_irqrestore(&cmd->t_state_lock, flags); 1987 spin_unlock_irqrestore(&cmd->t_state_lock, flags);
1988 1988
1989 transport_free_pages(cmd); 1989 transport_free_pages(cmd);
1990 transport_release_cmd(cmd); 1990 return transport_release_cmd(cmd);
1991 return;
1992} 1991}
1993 1992
1994void *transport_kmap_data_sg(struct se_cmd *cmd) 1993void *transport_kmap_data_sg(struct se_cmd *cmd)
@@ -2153,13 +2152,15 @@ static void transport_write_pending_qf(struct se_cmd *cmd)
2153 } 2152 }
2154} 2153}
2155 2154
2156void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) 2155int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
2157{ 2156{
2157 int ret = 0;
2158
2158 if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD)) { 2159 if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD)) {
2159 if (wait_for_tasks && (cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) 2160 if (wait_for_tasks && (cmd->se_cmd_flags & SCF_SCSI_TMR_CDB))
2160 transport_wait_for_tasks(cmd); 2161 transport_wait_for_tasks(cmd);
2161 2162
2162 transport_release_cmd(cmd); 2163 ret = transport_release_cmd(cmd);
2163 } else { 2164 } else {
2164 if (wait_for_tasks) 2165 if (wait_for_tasks)
2165 transport_wait_for_tasks(cmd); 2166 transport_wait_for_tasks(cmd);
@@ -2167,8 +2168,9 @@ void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
2167 if (cmd->se_lun) 2168 if (cmd->se_lun)
2168 transport_lun_remove_cmd(cmd); 2169 transport_lun_remove_cmd(cmd);
2169 2170
2170 transport_put_cmd(cmd); 2171 ret = transport_put_cmd(cmd);
2171 } 2172 }
2173 return ret;
2172} 2174}
2173EXPORT_SYMBOL(transport_generic_free_cmd); 2175EXPORT_SYMBOL(transport_generic_free_cmd);
2174 2176
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index 8a26f0d55fd1..1dcce9cc99b9 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -114,7 +114,7 @@ sense_reason_t transport_generic_new_cmd(struct se_cmd *);
114 114
115void target_execute_cmd(struct se_cmd *cmd); 115void target_execute_cmd(struct se_cmd *cmd);
116 116
117void transport_generic_free_cmd(struct se_cmd *, int); 117int transport_generic_free_cmd(struct se_cmd *, int);
118 118
119bool transport_wait_for_tasks(struct se_cmd *); 119bool transport_wait_for_tasks(struct se_cmd *);
120int transport_check_aborted_status(struct se_cmd *, int); 120int transport_check_aborted_status(struct se_cmd *, int);