diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-03-22 17:55:56 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-04-07 04:48:51 -0400 |
commit | 131e6abc674edb9f9a59090bb35bf6650569b7e7 (patch) | |
tree | 3baa38894c61d5fca1a99ae91a7ba9986c570d34 | |
parent | 68259b5aac13a57cba797b9605ed9812158f0e72 (diff) |
target: Add TFO->abort_task for aborted task resources release
Now that TASK_ABORTED status is not generated for all cases by
TMR ABORT_TASK + LUN_RESET, a new TFO->abort_task() caller is
necessary in order to give fabric drivers a chance to unmap
hardware / software resources before the se_cmd descriptor is
released via the normal TFO->release_cmd() codepath.
This patch adds TFO->aborted_task() in core_tmr_abort_task()
in place of the original transport_send_task_abort(), and
also updates all fabric drivers to implement this caller.
The fabric drivers that include changes to perform cleanup
via ->aborted_task() are:
- iscsi-target
- iser-target
- srpt
- tcm_qla2xxx
The fabric drivers that currently set ->aborted_task() to
NOPs are:
- loopback
- tcm_fc
- usb-gadget
- sbp-target
- vhost-scsi
For the latter five, there appears to be no additional cleanup
required before invoking TFO->release_cmd() to release the
se_cmd descriptor.
v2 changes:
- Move ->aborted_task() call into transport_cmd_finish_abort (Alex)
Cc: Alex Leung <amleung21@yahoo.com>
Cc: Mark Rustad <mark.d.rustad@intel.com>
Cc: Roland Dreier <roland@kernel.org>
Cc: Vu Pham <vu@mellanox.com>
Cc: Chris Boot <bootc@bootc.net>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Giridhar Malavali <giridhar.malavali@qlogic.com>
Cc: Saurav Kashyap <saurav.kashyap@qlogic.com>
Cc: Quinn Tran <quinn.tran@qlogic.com>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r-- | drivers/infiniband/ulp/isert/ib_isert.c | 19 | ||||
-rw-r--r-- | drivers/infiniband/ulp/srpt/ib_srpt.c | 9 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/tcm_qla2xxx.c | 16 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 13 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_configfs.c | 8 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_util.c | 4 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_util.h | 1 | ||||
-rw-r--r-- | drivers/target/loopback/tcm_loop.c | 6 | ||||
-rw-r--r-- | drivers/target/sbp/sbp_target.c | 6 | ||||
-rw-r--r-- | drivers/target/target_core_configfs.c | 4 | ||||
-rw-r--r-- | drivers/target/target_core_transport.c | 6 | ||||
-rw-r--r-- | drivers/target/tcm_fc/tcm_fc.h | 1 | ||||
-rw-r--r-- | drivers/target/tcm_fc/tfc_cmd.c | 5 | ||||
-rw-r--r-- | drivers/target/tcm_fc/tfc_conf.c | 1 | ||||
-rw-r--r-- | drivers/usb/gadget/tcm_usb_gadget.c | 6 | ||||
-rw-r--r-- | drivers/vhost/scsi.c | 6 | ||||
-rw-r--r-- | include/target/iscsi/iscsi_transport.h | 1 | ||||
-rw-r--r-- | include/target/target_core_fabric.h | 1 |
18 files changed, 111 insertions, 2 deletions
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 529d2cbfe45a..18ada7fb0fc9 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c | |||
@@ -2162,6 +2162,24 @@ isert_put_response(struct iscsi_conn *conn, struct iscsi_cmd *cmd) | |||
2162 | return isert_post_response(isert_conn, isert_cmd); | 2162 | return isert_post_response(isert_conn, isert_cmd); |
2163 | } | 2163 | } |
2164 | 2164 | ||
2165 | static void | ||
2166 | isert_aborted_task(struct iscsi_conn *conn, struct iscsi_cmd *cmd) | ||
2167 | { | ||
2168 | struct isert_cmd *isert_cmd = iscsit_priv_cmd(cmd); | ||
2169 | struct isert_conn *isert_conn = (struct isert_conn *)conn->context; | ||
2170 | struct isert_device *device = isert_conn->conn_device; | ||
2171 | |||
2172 | spin_lock_bh(&conn->cmd_lock); | ||
2173 | if (!list_empty(&cmd->i_conn_node)) | ||
2174 | list_del_init(&cmd->i_conn_node); | ||
2175 | spin_unlock_bh(&conn->cmd_lock); | ||
2176 | |||
2177 | if (cmd->data_direction == DMA_TO_DEVICE) | ||
2178 | iscsit_stop_dataout_timer(cmd); | ||
2179 | |||
2180 | device->unreg_rdma_mem(isert_cmd, isert_conn); | ||
2181 | } | ||
2182 | |||
2165 | static int | 2183 | static int |
2166 | isert_put_nopin(struct iscsi_cmd *cmd, struct iscsi_conn *conn, | 2184 | isert_put_nopin(struct iscsi_cmd *cmd, struct iscsi_conn *conn, |
2167 | bool nopout_response) | 2185 | bool nopout_response) |
@@ -3217,6 +3235,7 @@ static struct iscsit_transport iser_target_transport = { | |||
3217 | .iscsit_get_dataout = isert_get_dataout, | 3235 | .iscsit_get_dataout = isert_get_dataout, |
3218 | .iscsit_queue_data_in = isert_put_datain, | 3236 | .iscsit_queue_data_in = isert_put_datain, |
3219 | .iscsit_queue_status = isert_put_response, | 3237 | .iscsit_queue_status = isert_put_response, |
3238 | .iscsit_aborted_task = isert_aborted_task, | ||
3220 | }; | 3239 | }; |
3221 | 3240 | ||
3222 | static int __init isert_init(void) | 3241 | static int __init isert_init(void) |
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 0e537d8d0e47..f03aafdc3572 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c | |||
@@ -3081,6 +3081,14 @@ static void srpt_queue_tm_rsp(struct se_cmd *cmd) | |||
3081 | srpt_queue_response(cmd); | 3081 | srpt_queue_response(cmd); |
3082 | } | 3082 | } |
3083 | 3083 | ||
3084 | static void srpt_aborted_task(struct se_cmd *cmd) | ||
3085 | { | ||
3086 | struct srpt_send_ioctx *ioctx = container_of(cmd, | ||
3087 | struct srpt_send_ioctx, cmd); | ||
3088 | |||
3089 | srpt_unmap_sg_to_ib_sge(ioctx->ch, ioctx); | ||
3090 | } | ||
3091 | |||
3084 | static int srpt_queue_status(struct se_cmd *cmd) | 3092 | static int srpt_queue_status(struct se_cmd *cmd) |
3085 | { | 3093 | { |
3086 | struct srpt_send_ioctx *ioctx; | 3094 | struct srpt_send_ioctx *ioctx; |
@@ -3928,6 +3936,7 @@ static struct target_core_fabric_ops srpt_template = { | |||
3928 | .queue_data_in = srpt_queue_data_in, | 3936 | .queue_data_in = srpt_queue_data_in, |
3929 | .queue_status = srpt_queue_status, | 3937 | .queue_status = srpt_queue_status, |
3930 | .queue_tm_rsp = srpt_queue_tm_rsp, | 3938 | .queue_tm_rsp = srpt_queue_tm_rsp, |
3939 | .aborted_task = srpt_aborted_task, | ||
3931 | /* | 3940 | /* |
3932 | * Setup function pointers for generic logic in | 3941 | * Setup function pointers for generic logic in |
3933 | * target_core_fabric_configfs.c | 3942 | * target_core_fabric_configfs.c |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 788c4fe2b0c9..b23a0ffe140e 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c | |||
@@ -684,6 +684,20 @@ static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd) | |||
684 | qlt_xmit_tm_rsp(mcmd); | 684 | qlt_xmit_tm_rsp(mcmd); |
685 | } | 685 | } |
686 | 686 | ||
687 | static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd) | ||
688 | { | ||
689 | struct qla_tgt_cmd *cmd = container_of(se_cmd, | ||
690 | struct qla_tgt_cmd, se_cmd); | ||
691 | struct scsi_qla_host *vha = cmd->vha; | ||
692 | struct qla_hw_data *ha = vha->hw; | ||
693 | |||
694 | if (!cmd->sg_mapped) | ||
695 | return; | ||
696 | |||
697 | pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction); | ||
698 | cmd->sg_mapped = 0; | ||
699 | } | ||
700 | |||
687 | /* Local pointer to allocated TCM configfs fabric module */ | 701 | /* Local pointer to allocated TCM configfs fabric module */ |
688 | struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs; | 702 | struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs; |
689 | struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs; | 703 | struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs; |
@@ -1877,6 +1891,7 @@ static struct target_core_fabric_ops tcm_qla2xxx_ops = { | |||
1877 | .queue_data_in = tcm_qla2xxx_queue_data_in, | 1891 | .queue_data_in = tcm_qla2xxx_queue_data_in, |
1878 | .queue_status = tcm_qla2xxx_queue_status, | 1892 | .queue_status = tcm_qla2xxx_queue_status, |
1879 | .queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp, | 1893 | .queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp, |
1894 | .aborted_task = tcm_qla2xxx_aborted_task, | ||
1880 | /* | 1895 | /* |
1881 | * Setup function pointers for generic logic in | 1896 | * Setup function pointers for generic logic in |
1882 | * target_core_fabric_configfs.c | 1897 | * target_core_fabric_configfs.c |
@@ -1926,6 +1941,7 @@ static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { | |||
1926 | .queue_data_in = tcm_qla2xxx_queue_data_in, | 1941 | .queue_data_in = tcm_qla2xxx_queue_data_in, |
1927 | .queue_status = tcm_qla2xxx_queue_status, | 1942 | .queue_status = tcm_qla2xxx_queue_status, |
1928 | .queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp, | 1943 | .queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp, |
1944 | .aborted_task = tcm_qla2xxx_aborted_task, | ||
1929 | /* | 1945 | /* |
1930 | * Setup function pointers for generic logic in | 1946 | * Setup function pointers for generic logic in |
1931 | * target_core_fabric_configfs.c | 1947 | * target_core_fabric_configfs.c |
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index df0456abc4fd..27f37c92dff3 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -499,6 +499,18 @@ static int iscsit_queue_rsp(struct iscsi_conn *conn, struct iscsi_cmd *cmd) | |||
499 | return 0; | 499 | return 0; |
500 | } | 500 | } |
501 | 501 | ||
502 | static void iscsit_aborted_task(struct iscsi_conn *conn, struct iscsi_cmd *cmd) | ||
503 | { | ||
504 | bool scsi_cmd = (cmd->iscsi_opcode == ISCSI_OP_SCSI_CMD); | ||
505 | |||
506 | spin_lock_bh(&conn->cmd_lock); | ||
507 | if (!list_empty(&cmd->i_conn_node)) | ||
508 | list_del_init(&cmd->i_conn_node); | ||
509 | spin_unlock_bh(&conn->cmd_lock); | ||
510 | |||
511 | __iscsit_free_cmd(cmd, scsi_cmd, true); | ||
512 | } | ||
513 | |||
502 | static struct iscsit_transport iscsi_target_transport = { | 514 | static struct iscsit_transport iscsi_target_transport = { |
503 | .name = "iSCSI/TCP", | 515 | .name = "iSCSI/TCP", |
504 | .transport_type = ISCSI_TCP, | 516 | .transport_type = ISCSI_TCP, |
@@ -513,6 +525,7 @@ static struct iscsit_transport iscsi_target_transport = { | |||
513 | .iscsit_response_queue = iscsit_response_queue, | 525 | .iscsit_response_queue = iscsit_response_queue, |
514 | .iscsit_queue_data_in = iscsit_queue_rsp, | 526 | .iscsit_queue_data_in = iscsit_queue_rsp, |
515 | .iscsit_queue_status = iscsit_queue_rsp, | 527 | .iscsit_queue_status = iscsit_queue_rsp, |
528 | .iscsit_aborted_task = iscsit_aborted_task, | ||
516 | }; | 529 | }; |
517 | 530 | ||
518 | static int __init iscsi_target_init_module(void) | 531 | static int __init iscsi_target_init_module(void) |
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index fe35dcbacb14..ae03f3e5de1e 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c | |||
@@ -1821,6 +1821,13 @@ static void lio_queue_tm_rsp(struct se_cmd *se_cmd) | |||
1821 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state); | 1821 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state); |
1822 | } | 1822 | } |
1823 | 1823 | ||
1824 | static void lio_aborted_task(struct se_cmd *se_cmd) | ||
1825 | { | ||
1826 | struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); | ||
1827 | |||
1828 | cmd->conn->conn_transport->iscsit_aborted_task(cmd->conn, cmd); | ||
1829 | } | ||
1830 | |||
1824 | static char *lio_tpg_get_endpoint_wwn(struct se_portal_group *se_tpg) | 1831 | static char *lio_tpg_get_endpoint_wwn(struct se_portal_group *se_tpg) |
1825 | { | 1832 | { |
1826 | struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr; | 1833 | struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr; |
@@ -2005,6 +2012,7 @@ int iscsi_target_register_configfs(void) | |||
2005 | fabric->tf_ops.queue_data_in = &lio_queue_data_in; | 2012 | fabric->tf_ops.queue_data_in = &lio_queue_data_in; |
2006 | fabric->tf_ops.queue_status = &lio_queue_status; | 2013 | fabric->tf_ops.queue_status = &lio_queue_status; |
2007 | fabric->tf_ops.queue_tm_rsp = &lio_queue_tm_rsp; | 2014 | fabric->tf_ops.queue_tm_rsp = &lio_queue_tm_rsp; |
2015 | fabric->tf_ops.aborted_task = &lio_aborted_task; | ||
2008 | /* | 2016 | /* |
2009 | * Setup function pointers for generic logic in target_core_fabric_configfs.c | 2017 | * Setup function pointers for generic logic in target_core_fabric_configfs.c |
2010 | */ | 2018 | */ |
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index e655b042ed18..53e157cb8c54 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c | |||
@@ -705,8 +705,8 @@ void iscsit_release_cmd(struct iscsi_cmd *cmd) | |||
705 | } | 705 | } |
706 | EXPORT_SYMBOL(iscsit_release_cmd); | 706 | EXPORT_SYMBOL(iscsit_release_cmd); |
707 | 707 | ||
708 | static void __iscsit_free_cmd(struct iscsi_cmd *cmd, bool scsi_cmd, | 708 | void __iscsit_free_cmd(struct iscsi_cmd *cmd, bool scsi_cmd, |
709 | bool check_queues) | 709 | bool check_queues) |
710 | { | 710 | { |
711 | struct iscsi_conn *conn = cmd->conn; | 711 | struct iscsi_conn *conn = cmd->conn; |
712 | 712 | ||
diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h index 561a424d1980..a68508c4fec8 100644 --- a/drivers/target/iscsi/iscsi_target_util.h +++ b/drivers/target/iscsi/iscsi_target_util.h | |||
@@ -30,6 +30,7 @@ extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_co | |||
30 | extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *); | 30 | extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *); |
31 | extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *); | 31 | extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *); |
32 | extern void iscsit_release_cmd(struct iscsi_cmd *); | 32 | extern void iscsit_release_cmd(struct iscsi_cmd *); |
33 | extern void __iscsit_free_cmd(struct iscsi_cmd *, bool, bool); | ||
33 | extern void iscsit_free_cmd(struct iscsi_cmd *, bool); | 34 | extern void iscsit_free_cmd(struct iscsi_cmd *, bool); |
34 | extern int iscsit_check_session_usage_count(struct iscsi_session *); | 35 | extern int iscsit_check_session_usage_count(struct iscsi_session *); |
35 | extern void iscsit_dec_session_usage_count(struct iscsi_session *); | 36 | extern void iscsit_dec_session_usage_count(struct iscsi_session *); |
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index a49ef0a49fa9..bdc1ad82d293 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c | |||
@@ -919,6 +919,11 @@ static void tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd) | |||
919 | wake_up(&tl_tmr->tl_tmr_wait); | 919 | wake_up(&tl_tmr->tl_tmr_wait); |
920 | } | 920 | } |
921 | 921 | ||
922 | static void tcm_loop_aborted_task(struct se_cmd *se_cmd) | ||
923 | { | ||
924 | return; | ||
925 | } | ||
926 | |||
922 | static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba) | 927 | static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba) |
923 | { | 928 | { |
924 | switch (tl_hba->tl_proto_id) { | 929 | switch (tl_hba->tl_proto_id) { |
@@ -1487,6 +1492,7 @@ static int tcm_loop_register_configfs(void) | |||
1487 | fabric->tf_ops.queue_data_in = &tcm_loop_queue_data_in; | 1492 | fabric->tf_ops.queue_data_in = &tcm_loop_queue_data_in; |
1488 | fabric->tf_ops.queue_status = &tcm_loop_queue_status; | 1493 | fabric->tf_ops.queue_status = &tcm_loop_queue_status; |
1489 | fabric->tf_ops.queue_tm_rsp = &tcm_loop_queue_tm_rsp; | 1494 | fabric->tf_ops.queue_tm_rsp = &tcm_loop_queue_tm_rsp; |
1495 | fabric->tf_ops.aborted_task = &tcm_loop_aborted_task; | ||
1490 | 1496 | ||
1491 | /* | 1497 | /* |
1492 | * Setup function pointers for generic logic in target_core_fabric_configfs.c | 1498 | * Setup function pointers for generic logic in target_core_fabric_configfs.c |
diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 24884cac19ce..ad04ea928e4f 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c | |||
@@ -1846,6 +1846,11 @@ static void sbp_queue_tm_rsp(struct se_cmd *se_cmd) | |||
1846 | { | 1846 | { |
1847 | } | 1847 | } |
1848 | 1848 | ||
1849 | static void sbp_aborted_task(struct se_cmd *se_cmd) | ||
1850 | { | ||
1851 | return; | ||
1852 | } | ||
1853 | |||
1849 | static int sbp_check_stop_free(struct se_cmd *se_cmd) | 1854 | static int sbp_check_stop_free(struct se_cmd *se_cmd) |
1850 | { | 1855 | { |
1851 | struct sbp_target_request *req = container_of(se_cmd, | 1856 | struct sbp_target_request *req = container_of(se_cmd, |
@@ -2526,6 +2531,7 @@ static struct target_core_fabric_ops sbp_ops = { | |||
2526 | .queue_data_in = sbp_queue_data_in, | 2531 | .queue_data_in = sbp_queue_data_in, |
2527 | .queue_status = sbp_queue_status, | 2532 | .queue_status = sbp_queue_status, |
2528 | .queue_tm_rsp = sbp_queue_tm_rsp, | 2533 | .queue_tm_rsp = sbp_queue_tm_rsp, |
2534 | .aborted_task = sbp_aborted_task, | ||
2529 | .check_stop_free = sbp_check_stop_free, | 2535 | .check_stop_free = sbp_check_stop_free, |
2530 | 2536 | ||
2531 | .fabric_make_wwn = sbp_make_tport, | 2537 | .fabric_make_wwn = sbp_make_tport, |
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index f0e85b119692..60a9ae6df763 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c | |||
@@ -457,6 +457,10 @@ static int target_fabric_tf_ops_check( | |||
457 | pr_err("Missing tfo->queue_tm_rsp()\n"); | 457 | pr_err("Missing tfo->queue_tm_rsp()\n"); |
458 | return -EINVAL; | 458 | return -EINVAL; |
459 | } | 459 | } |
460 | if (!tfo->aborted_task) { | ||
461 | pr_err("Missing tfo->aborted_task()\n"); | ||
462 | return -EINVAL; | ||
463 | } | ||
460 | /* | 464 | /* |
461 | * We at least require tfo->fabric_make_wwn(), tfo->fabric_drop_wwn() | 465 | * We at least require tfo->fabric_make_wwn(), tfo->fabric_drop_wwn() |
462 | * tfo->fabric_make_tpg() and tfo->fabric_drop_tpg() in | 466 | * tfo->fabric_make_tpg() and tfo->fabric_drop_tpg() in |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 51a375453d9b..9393544fb471 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -605,6 +605,12 @@ void transport_cmd_finish_abort(struct se_cmd *cmd, int remove) | |||
605 | { | 605 | { |
606 | if (cmd->se_cmd_flags & SCF_SE_LUN_CMD) | 606 | if (cmd->se_cmd_flags & SCF_SE_LUN_CMD) |
607 | transport_lun_remove_cmd(cmd); | 607 | transport_lun_remove_cmd(cmd); |
608 | /* | ||
609 | * Allow the fabric driver to unmap any resources before | ||
610 | * releasing the descriptor via TFO->release_cmd() | ||
611 | */ | ||
612 | if (remove) | ||
613 | cmd->se_tfo->aborted_task(cmd); | ||
608 | 614 | ||
609 | if (transport_cmd_check_stop_to_fabric(cmd)) | 615 | if (transport_cmd_check_stop_to_fabric(cmd)) |
610 | return; | 616 | return; |
diff --git a/drivers/target/tcm_fc/tcm_fc.h b/drivers/target/tcm_fc/tcm_fc.h index 752863acecb8..4f4b97161228 100644 --- a/drivers/target/tcm_fc/tcm_fc.h +++ b/drivers/target/tcm_fc/tcm_fc.h | |||
@@ -163,6 +163,7 @@ int ft_write_pending_status(struct se_cmd *); | |||
163 | u32 ft_get_task_tag(struct se_cmd *); | 163 | u32 ft_get_task_tag(struct se_cmd *); |
164 | int ft_get_cmd_state(struct se_cmd *); | 164 | int ft_get_cmd_state(struct se_cmd *); |
165 | void ft_queue_tm_resp(struct se_cmd *); | 165 | void ft_queue_tm_resp(struct se_cmd *); |
166 | void ft_aborted_task(struct se_cmd *); | ||
166 | 167 | ||
167 | /* | 168 | /* |
168 | * other internal functions. | 169 | * other internal functions. |
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index 8b2c1aaf81de..01cf37f212c3 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c | |||
@@ -426,6 +426,11 @@ void ft_queue_tm_resp(struct se_cmd *se_cmd) | |||
426 | ft_send_resp_code(cmd, code); | 426 | ft_send_resp_code(cmd, code); |
427 | } | 427 | } |
428 | 428 | ||
429 | void ft_aborted_task(struct se_cmd *se_cmd) | ||
430 | { | ||
431 | return; | ||
432 | } | ||
433 | |||
429 | static void ft_send_work(struct work_struct *work); | 434 | static void ft_send_work(struct work_struct *work); |
430 | 435 | ||
431 | /* | 436 | /* |
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c index e879da81ad93..b8b5a719a784 100644 --- a/drivers/target/tcm_fc/tfc_conf.c +++ b/drivers/target/tcm_fc/tfc_conf.c | |||
@@ -536,6 +536,7 @@ static struct target_core_fabric_ops ft_fabric_ops = { | |||
536 | .queue_data_in = ft_queue_data_in, | 536 | .queue_data_in = ft_queue_data_in, |
537 | .queue_status = ft_queue_status, | 537 | .queue_status = ft_queue_status, |
538 | .queue_tm_rsp = ft_queue_tm_resp, | 538 | .queue_tm_rsp = ft_queue_tm_resp, |
539 | .aborted_task = ft_aborted_task, | ||
539 | /* | 540 | /* |
540 | * Setup function pointers for generic logic in | 541 | * Setup function pointers for generic logic in |
541 | * target_core_fabric_configfs.c | 542 | * target_core_fabric_configfs.c |
diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index 0f8aad78b54f..f9afa4a4ec3c 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c | |||
@@ -1471,6 +1471,11 @@ static void usbg_queue_tm_rsp(struct se_cmd *se_cmd) | |||
1471 | { | 1471 | { |
1472 | } | 1472 | } |
1473 | 1473 | ||
1474 | static void usbg_aborted_task(struct se_cmd *se_cmd) | ||
1475 | { | ||
1476 | return; | ||
1477 | } | ||
1478 | |||
1474 | static const char *usbg_check_wwn(const char *name) | 1479 | static const char *usbg_check_wwn(const char *name) |
1475 | { | 1480 | { |
1476 | const char *n; | 1481 | const char *n; |
@@ -1897,6 +1902,7 @@ static struct target_core_fabric_ops usbg_ops = { | |||
1897 | .queue_data_in = usbg_send_read_response, | 1902 | .queue_data_in = usbg_send_read_response, |
1898 | .queue_status = usbg_send_status_response, | 1903 | .queue_status = usbg_send_status_response, |
1899 | .queue_tm_rsp = usbg_queue_tm_rsp, | 1904 | .queue_tm_rsp = usbg_queue_tm_rsp, |
1905 | .aborted_task = usbg_aborted_task, | ||
1900 | .check_stop_free = usbg_check_stop_free, | 1906 | .check_stop_free = usbg_check_stop_free, |
1901 | 1907 | ||
1902 | .fabric_make_wwn = usbg_make_tport, | 1908 | .fabric_make_wwn = usbg_make_tport, |
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index e48d4a672580..4a473355020f 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c | |||
@@ -539,6 +539,11 @@ static void tcm_vhost_queue_tm_rsp(struct se_cmd *se_cmd) | |||
539 | return; | 539 | return; |
540 | } | 540 | } |
541 | 541 | ||
542 | static void tcm_vhost_aborted_task(struct se_cmd *se_cmd) | ||
543 | { | ||
544 | return; | ||
545 | } | ||
546 | |||
542 | static void tcm_vhost_free_evt(struct vhost_scsi *vs, struct tcm_vhost_evt *evt) | 547 | static void tcm_vhost_free_evt(struct vhost_scsi *vs, struct tcm_vhost_evt *evt) |
543 | { | 548 | { |
544 | vs->vs_events_nr--; | 549 | vs->vs_events_nr--; |
@@ -2131,6 +2136,7 @@ static struct target_core_fabric_ops tcm_vhost_ops = { | |||
2131 | .queue_data_in = tcm_vhost_queue_data_in, | 2136 | .queue_data_in = tcm_vhost_queue_data_in, |
2132 | .queue_status = tcm_vhost_queue_status, | 2137 | .queue_status = tcm_vhost_queue_status, |
2133 | .queue_tm_rsp = tcm_vhost_queue_tm_rsp, | 2138 | .queue_tm_rsp = tcm_vhost_queue_tm_rsp, |
2139 | .aborted_task = tcm_vhost_aborted_task, | ||
2134 | /* | 2140 | /* |
2135 | * Setup callers for generic logic in target_core_fabric_configfs.c | 2141 | * Setup callers for generic logic in target_core_fabric_configfs.c |
2136 | */ | 2142 | */ |
diff --git a/include/target/iscsi/iscsi_transport.h b/include/target/iscsi/iscsi_transport.h index 4483fadfa68d..8d19339292b8 100644 --- a/include/target/iscsi/iscsi_transport.h +++ b/include/target/iscsi/iscsi_transport.h | |||
@@ -21,6 +21,7 @@ struct iscsit_transport { | |||
21 | int (*iscsit_get_dataout)(struct iscsi_conn *, struct iscsi_cmd *, bool); | 21 | int (*iscsit_get_dataout)(struct iscsi_conn *, struct iscsi_cmd *, bool); |
22 | int (*iscsit_queue_data_in)(struct iscsi_conn *, struct iscsi_cmd *); | 22 | int (*iscsit_queue_data_in)(struct iscsi_conn *, struct iscsi_cmd *); |
23 | int (*iscsit_queue_status)(struct iscsi_conn *, struct iscsi_cmd *); | 23 | int (*iscsit_queue_status)(struct iscsi_conn *, struct iscsi_cmd *); |
24 | void (*iscsit_aborted_task)(struct iscsi_conn *, struct iscsi_cmd *); | ||
24 | }; | 25 | }; |
25 | 26 | ||
26 | static inline void *iscsit_priv_cmd(struct iscsi_cmd *cmd) | 27 | static inline void *iscsit_priv_cmd(struct iscsi_cmd *cmd) |
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 0218d689b3d7..1d1043644b9b 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h | |||
@@ -62,6 +62,7 @@ struct target_core_fabric_ops { | |||
62 | int (*queue_data_in)(struct se_cmd *); | 62 | int (*queue_data_in)(struct se_cmd *); |
63 | int (*queue_status)(struct se_cmd *); | 63 | int (*queue_status)(struct se_cmd *); |
64 | void (*queue_tm_rsp)(struct se_cmd *); | 64 | void (*queue_tm_rsp)(struct se_cmd *); |
65 | void (*aborted_task)(struct se_cmd *); | ||
65 | /* | 66 | /* |
66 | * fabric module calls for target_core_fabric_configfs.c | 67 | * fabric module calls for target_core_fabric_configfs.c |
67 | */ | 68 | */ |