[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