[PATCH v2 3/3] scsi: core: do not retry passthrough requests on disconnected targets

From: Sarthak Kukreti

Date: Fri Nov 13 2026 - 03:49:41 EST


Unlike scsi_decide_disposition(), scsi_check_passthrough() matches
SCMD_FAILURE_RESULT_ANY before checking the host byte and returns
-EAGAIN on DID_NO_CONNECT, DID_BAD_TARGET, and DID_TRANSPORT_FAILFAST.
Callers using SCMD_FAILURE_RESULT_ANY (such as sd_sync_cache())
therefore retry passthrough commands against disconnected targets.

Return 0 from scsi_check_passthrough() when the host byte is
DID_NO_CONNECT, DID_BAD_TARGET, or DID_TRANSPORT_FAILFAST, and update
scsi_lib_test_any_failure().

Fixes: 994724e6b3f0 ("scsi: core: Allow passthrough to request midlayer retries")
Signed-off-by: Sarthak Kukreti <sarthakkukreti@xxxxxxxxxx>
---
drivers/scsi/scsi_lib.c | 5 +++++
drivers/scsi/scsi_lib_test.c | 9 ++++++++-
2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index af27fd3df8d4..fa16a75e810c 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -219,6 +219,11 @@ static int scsi_check_passthrough(struct scsi_cmnd *scmd,
if (!scmd->result)
return 0;

+ if (host_byte(scmd->result) == DID_NO_CONNECT ||
+ host_byte(scmd->result) == DID_BAD_TARGET ||
+ host_byte(scmd->result) == DID_TRANSPORT_FAILFAST)
+ return 0;
+
if (!failures)
return 0;

diff --git a/drivers/scsi/scsi_lib_test.c b/drivers/scsi/scsi_lib_test.c
index ae8af0e0047a..aafafe676098 100644
--- a/drivers/scsi/scsi_lib_test.c
+++ b/drivers/scsi/scsi_lib_test.c
@@ -184,8 +184,15 @@ static void scsi_lib_test_any_failure(struct kunit *test)

/* Match SCMD_FAILURE_RESULT_ANY */
failures.failure_definitions = any_failure_defs;
- sc.result = DID_TRANSPORT_FAILFAST << 16;
+ sc.result = DID_ERROR << 16;
KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, &failures));
+
+ sc.result = DID_NO_CONNECT << 16;
+ KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures));
+ sc.result = DID_BAD_TARGET << 16;
+ KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures));
+ sc.result = DID_TRANSPORT_FAILFAST << 16;
+ KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures));
}

static void scsi_lib_test_any_status(struct kunit *test)
--
2.56.0.611.g1030f0b940-goog