drivers/target/target_core_file.c | 2 +- 5 files changed, 51 insertions(+), 10 deletions(-)
Driver (and enclosure) only fixes. Most are obvious. The big change
is in the tcm_loop driver to add command draining to error handling
(the lack of which was causing hangs with the potential for double use
crashes).
The patch is available here:
git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git scsi-fixes
The short changelog is:
Greg Kroah-Hartman (1):
scsi: ses: Handle positive SCSI error from ses_recv_diag()
Josef Bacik (1):
scsi: target: tcm_loop: Drain commands in target_reset handler
Thinh Nguyen (1):
scsi: target: file: Use kzalloc_flex for aio_cmd
Tyllis Xu (1):
scsi: ibmvfc: Fix OOB access in ibmvfc_discover_targets_done()
Yihang Li (1):
scsi: scsi_transport_sas: Fix the maximum channel scanning issue
And the diffstat:
drivers/scsi/ibmvscsi/ibmvfc.c | 3 ++-
drivers/scsi/scsi_transport_sas.c | 2 +-
drivers/scsi/ses.c | 2 +-
drivers/target/loopback/tcm_loop.c | 52
+++++++++++++++++++++++++++++++++-----
drivers/target/target_core_file.c | 2 +-
5 files changed, 51 insertions(+), 10 deletions(-)
With full diff below.
James
---
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c
b/drivers/scsi/ibmvscsi/ibmvfc.c
index a20fce04fe79..3dd2adda195e 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -4966,7 +4966,8 @@ static void ibmvfc_discover_targets_done(struct
ibmvfc_event *evt)
switch (mad_status) {
case IBMVFC_MAD_SUCCESS:
ibmvfc_dbg(vhost, "Discover Targets succeeded\n");
- vhost->num_targets = be32_to_cpu(rsp->num_written);
+ vhost->num_targets = min_t(u32, be32_to_cpu(rsp-
>num_written),
+ max_targets);
ibmvfc_set_host_action(vhost,
IBMVFC_HOST_ACTION_ALLOC_TGTS);
break;
case IBMVFC_MAD_FAILED:
diff --git a/drivers/scsi/scsi_transport_sas.c
b/drivers/scsi/scsi_transport_sas.c
index 12124f9d5ccd..13412702188e 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -1734,7 +1734,7 @@ static int sas_user_scan(struct Scsi_Host *shost,
uint channel,
break;
default:
- if (channel < shost->max_channel) {
+ if (channel <= shost->max_channel) {
res = scsi_scan_host_selected(shost, channel,
id, lun,
SCSI_SCAN_MANUAL);
} else {
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index 8e1686358e25..4c348645b04e 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -215,7 +215,7 @@ static unsigned char
*ses_get_page2_descriptor(struct enclosure_device *edev,
unsigned char *type_ptr = ses_dev->page1_types;
unsigned char *desc_ptr = ses_dev->page2 + 8;
- if (ses_recv_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len)
< 0)
+ if (ses_recv_diag(sdev, 2, ses_dev->page2, ses_dev-
>page2_len))
return NULL;
for (i = 0; i < ses_dev->page1_num_types; i++, type_ptr += 4)
{
diff --git a/drivers/target/loopback/tcm_loop.c
b/drivers/target/loopback/tcm_loop.c
index d668bd19fd4a..528883d989b8 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -26,6 +26,7 @@
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/configfs.h>
+#include <linux/blk-mq.h>
#include <scsi/scsi.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsi_host.h>
@@ -269,15 +270,27 @@ 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(sc->device-
>host);
+ 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;
@@ -286,11 +299,38 @@ static int tcm_loop_target_reset(struct scsi_cmnd
*sc)
* Locate the tl_tpg pointer from TargetID in sc->device->id
*/
tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
- if (tl_tpg) {
- tl_tpg->tl_transport_status = TCM_TRANSPORT_ONLINE;
- return SUCCESS;
- }
- return FAILED;
+ 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 = {
diff --git a/drivers/target/target_core_file.c
b/drivers/target/target_core_file.c
index 3ae1f7137d9d..3d593af30aa5 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -276,7 +276,7 @@ fd_execute_rw_aio(struct se_cmd *cmd, struct
scatterlist *sgl, u32 sgl_nents,
ssize_t len = 0;
int ret = 0, i;
- aio_cmd = kmalloc_flex(*aio_cmd, bvecs, sgl_nents);
+ aio_cmd = kzalloc_flex(*aio_cmd, bvecs, sgl_nents);
if (!aio_cmd)
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
The pull request you sent on Fri, 27 Mar 2026 18:18:30 -0400: > git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git scsi-fixes has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/afb54c14047780b97719e8b6e4ea11a0cecc2739 Thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/prtracker.html
© 2016 - 2026 Red Hat, Inc.