Linux SCSI subsystem development
 help / color / mirror / Atom feed
From: Brian Bunker <brian@purestorage.com>
To: linux-scsi@vger.kernel.org
Cc: "Martin K . Petersen" <mkp@kernel.org>,
	"James E . J . Bottomley" <James.Bottomley@HansenPartnership.com>,
	Hannes Reinecke <hare@kernel.org>,
	Bart Van Assche <bvanassche@acm.org>,
	Krishna Kant <krishna.kant@purestorage.com>
Subject: [PATCH 4/4] scsi: core: Match ULDs to logical units in the ALUA unavailable state
Date: Wed, 28 Oct 2026 11:42:16 -0700	[thread overview]
Message-ID: <20261028184216.25453-5-brian@purestorage.com> (raw)
In-Reply-To: <20261028184216.25453-1-brian@purestorage.com>

scsi_bus_match() only matches devices with peripheral qualifier 000b,
so a LU that is in the ALUA unavailable state on a target port when
the host scans it never gets an upper-level driver on that path. When
the target port becomes available again, nothing binds sd and the path
stays unusable until the device is deleted and rescanned. A host that
was already running when the path became unavailable keeps sd bound,
so the result depends on when the host scanned.

Peripheral qualifier 001b cannot be matched on its own: an unmapped
LUN reports it as well, and some targets report every possible LUN in
REPORT LUNS. Binding sd to all of those would create disks with no
backing LU.

The SCSI core now reads the access state of a device that supports
target port groups with REPORT TARGET PORT GROUPS before the device is
registered, and an unmapped LUN fails that command. Also match PQ 001b
devices whose access state is unavailable. sd then binds to the
unavailable path like it does to a standby path, the path stays in the
multipath map as a failed path, and the existing UNIT ATTENTION
handling brings it back when the target port becomes available.

This is the same situation as a path in the standby state, to which sd
already binds: SPC-4 requires READ CAPACITY in neither state. The
cached INQUIRY data in sysfs keeps the peripheral qualifier reported at
scan time, like the rest of the INQUIRY data; access_state shows the
current ALUA state.

Co-developed-by: Krishna Kant <krishna.kant@purestorage.com>
Signed-off-by: Krishna Kant <krishna.kant@purestorage.com>
Signed-off-by: Brian Bunker <brian@purestorage.com>
---
 drivers/scsi/scsi_sysfs.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index fe54792ed69e..8d90f0c715ce 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -539,7 +539,19 @@ static int scsi_bus_match(struct device *dev, const struct device_driver *gendrv
 	sdp = to_scsi_device(dev);
 	if (sdp->no_uld_attach)
 		return 0;
-	return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0;
+	if (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)
+		return 1;
+	/*
+	 * Peripheral qualifier 001b is also what a LU reports while it is in
+	 * the ALUA unavailable state on this target port (SPC-4 5.15.2.4.5).
+	 * scsi_add_lun() reads that state with REPORT TARGET PORT GROUPS
+	 * before the device is registered. A LUN that is not mapped reports
+	 * 001b too, but fails REPORT TARGET PORT GROUPS and so is not
+	 * matched.
+	 */
+	return sdp->inq_periph_qual == SCSI_INQ_PQ_NOT_CON &&
+	       (sdp->access_state & SCSI_ACCESS_STATE_MASK) ==
+			SCSI_ACCESS_STATE_UNAVAILABLE;
 }
 
 static int scsi_bus_uevent(const struct device *dev, struct kobj_uevent_env *env)
-- 
2.56.0


  parent reply	other threads:[~2026-10-28 18:42 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-28 18:42 [PATCH 0/4] scsi: Bind sd to LUs in the ALUA unavailable state Brian Bunker
2026-10-28 18:42 ` [PATCH 1/4] scsi: core: Move REPORT TARGET PORT GROUPS into the SCSI core Brian Bunker
2026-10-28 18:42 ` [PATCH 2/4] scsi: core: Read the ALUA access state when a device is scanned Brian Bunker
2026-10-28 18:42 ` [PATCH 3/4] scsi: scsi_dh_alua: Start a port group in the scanned access state Brian Bunker
2026-10-28 18:42 ` Brian Bunker [this message]
2026-10-28 18:59   ` [PATCH 4/4] scsi: core: Match ULDs to logical units in the ALUA unavailable state sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261028184216.25453-5-brian@purestorage.com \
    --to=brian@purestorage.com \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=bvanassche@acm.org \
    --cc=hare@kernel.org \
    --cc=krishna.kant@purestorage.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=mkp@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox