diff options
Diffstat (limited to 'drivers/target/loopback/tcm_loop.c')
| -rw-r--r-- | drivers/target/loopback/tcm_loop.c | 64 |
1 files changed, 0 insertions, 64 deletions
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 156f934049f1..c6b64000983c 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -269,69 +269,6 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc) return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED; } -static bool tcm_loop_flush_work_iter(struct request *rq, void *data) -{ - struct scsi_cmnd *sc = blk_mq_rq_to_pdu(rq); - struct tcm_loop_cmd *tl_cmd = scsi_cmd_priv(sc); - struct se_cmd *se_cmd = &tl_cmd->tl_se_cmd; - - flush_work(&se_cmd->work); - return true; -} - -static int tcm_loop_target_reset(struct scsi_cmnd *sc) -{ - struct tcm_loop_hba *tl_hba; - struct tcm_loop_tpg *tl_tpg; - struct Scsi_Host *sh = sc->device->host; - int ret; - - /* - * Locate the tcm_loop_hba_t pointer - */ - tl_hba = *(struct tcm_loop_hba **)shost_priv(sh); - if (!tl_hba) { - pr_err("Unable to perform device reset without active I_T Nexus\n"); - return FAILED; - } - /* - * Locate the tl_tpg pointer from TargetID in sc->device->id - */ - tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id]; - if (!tl_tpg) - return FAILED; - - /* - * Issue a LUN_RESET to drain all commands that the target core - * knows about. This handles commands not yet marked CMD_T_COMPLETE. - */ - ret = tcm_loop_issue_tmr(tl_tpg, sc->device->lun, 0, TMR_LUN_RESET); - if (ret != TMR_FUNCTION_COMPLETE) - return FAILED; - - /* - * Flush any deferred target core completion work that may still be - * queued. Commands that already had CMD_T_COMPLETE set before the TMR - * are skipped by the TMR drain, but their async completion work - * (transport_lun_remove_cmd → percpu_ref_put, release_cmd → scsi_done) - * may still be pending in target_completion_wq. - * - * The SCSI EH will reuse in-flight scsi_cmnd structures for recovery - * commands (e.g. TUR) immediately after this handler returns SUCCESS — - * if deferred work is still pending, the memset in queuecommand would - * zero the se_cmd while the work accesses it, leaking the LUN - * percpu_ref and hanging configfs unlink forever. - * - * Use blk_mq_tagset_busy_iter() to find all started requests and - * flush_work() on each — the same pattern used by mpi3mr, scsi_debug, - * and other SCSI drivers to drain outstanding commands during reset. - */ - blk_mq_tagset_busy_iter(&sh->tag_set, tcm_loop_flush_work_iter, NULL); - - tl_tpg->tl_transport_status = TCM_TRANSPORT_ONLINE; - return SUCCESS; -} - static const struct scsi_host_template tcm_loop_driver_template = { .show_info = tcm_loop_show_info, .proc_name = "tcm_loopback", @@ -340,7 +277,6 @@ static const struct scsi_host_template tcm_loop_driver_template = { .change_queue_depth = scsi_change_queue_depth, .eh_abort_handler = tcm_loop_abort_task, .eh_device_reset_handler = tcm_loop_device_reset, - .eh_target_reset_handler = tcm_loop_target_reset, .this_id = -1, .sg_tablesize = 256, .max_sectors = 0xFFFF, |
