diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-05-31 03:46:11 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-05-31 04:21:23 -0400 |
commit | d5ddad4168348337d98d6b8f156a3892de444411 (patch) | |
tree | 8d9151a21c95709ccc0b58cd60a61beba8248459 | |
parent | cea4dcfdad926a27a18e188720efe0f2c9403456 (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.c | 28 | ||||
-rw-r--r-- | include/target/target_core_fabric.h | 2 |
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); | |||
65 | static void transport_handle_queue_full(struct se_cmd *cmd, | 65 | static void transport_handle_queue_full(struct se_cmd *cmd, |
66 | struct se_device *dev); | 66 | struct se_device *dev); |
67 | static int transport_generic_get_mem(struct se_cmd *cmd); | 67 | static int transport_generic_get_mem(struct se_cmd *cmd); |
68 | static void transport_put_cmd(struct se_cmd *cmd); | 68 | static int transport_put_cmd(struct se_cmd *cmd); |
69 | static void target_complete_ok_work(struct work_struct *work); | 69 | static void target_complete_ok_work(struct work_struct *work); |
70 | 70 | ||
71 | int init_se_kmem_caches(void) | 71 | int 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 | */ |
1947 | static void transport_release_cmd(struct se_cmd *cmd) | 1947 | static 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 | */ |
1972 | static void transport_put_cmd(struct se_cmd *cmd) | 1972 | static 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 | ||
1994 | void *transport_kmap_data_sg(struct se_cmd *cmd) | 1993 | void *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 | ||
2156 | void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) | 2155 | int 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 | } |
2173 | EXPORT_SYMBOL(transport_generic_free_cmd); | 2175 | EXPORT_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 | ||
115 | void target_execute_cmd(struct se_cmd *cmd); | 115 | void target_execute_cmd(struct se_cmd *cmd); |
116 | 116 | ||
117 | void transport_generic_free_cmd(struct se_cmd *, int); | 117 | int transport_generic_free_cmd(struct se_cmd *, int); |
118 | 118 | ||
119 | bool transport_wait_for_tasks(struct se_cmd *); | 119 | bool transport_wait_for_tasks(struct se_cmd *); |
120 | int transport_check_aborted_status(struct se_cmd *, int); | 120 | int transport_check_aborted_status(struct se_cmd *, int); |