* [PATCH] scsi: target: compare all six ISID bytes when identifying a nexus
@ 2026-11-09 13:12 Ciro Iriarte
2026-11-09 13:30 ` sashiko-bot
2026-11-09 14:31 ` [PATCH v2] " Ciro Iriarte
0 siblings, 2 replies; 3+ messages in thread
From: Ciro Iriarte @ 2026-11-09 13:12 UTC (permalink / raw)
To: Martin K. Petersen; +Cc: target-devel, linux-scsi, linux-kernel, stable
lio_sess_get_initiator_sid() reports the ISID as twelve hex digits, and
iSCSI TransportIDs carry the same digits. __transport_register_session(),
__core_scsi3_do_alloc_registration() and
core_scsi3_alloc_aptpl_registration() turn that text into
sess_bin_isid and pr_reg_bin_isid with get_unaligned_be64(), which takes
the first eight characters, i.e. the first four ISID bytes.
open-iscsi ISIDs start with 00023d00 and differ only in the qualifier in
the last two bytes, so every session of one initiator gets the same
binary ISID. target_scsi2_reservation_check() and
target_scsi3_pr_reservation_check() then treat any session of the
reservation holder's initiator as the holder:
- after RESERVE(6) on one session, another session of the same
initiator can still write;
- with a Write Exclusive persistent reservation, another session that
is not registered, or registered but not the holder, can still write.
Reproduced with two open-iscsi sessions (ifaces default and if2) to a
ramdisk LUN: on v6.12.113 every command from the second session
completes with GOOD; with this patch TEST UNIT READY and WRITE(10)
under RESERVE(6), and WRITE(10) under Write Exclusive, return
RESERVATION CONFLICT, and READ(10) is still allowed.
Convert all six bytes. Text that is not exactly twelve hex digits keeps
the old conversion of its first eight characters, now copied into a
zeroed buffer so that a shorter string, such as an initiator_sid written
to res_aptpl_metadata, is not read past its end.
An all-zero ISID now converts to 0, which
target_scsi2_reservation_reserve() took to mean "no ISID". Set
DRF_SPC2_RESERVATIONS_WITH_ISID when the fabric reports ISIDs instead.
Also update the TransportID parser comment that referred to the
get_unaligned_be64() read.
Initiators that relied on the old behaviour, reserving through one
session and writing through another without registering it, will now
see RESERVATION CONFLICT, as SPC requires.
Fixes: e48354ce078c ("iscsi-target: Add iSCSI fabric support for target v4.1")
Cc: stable@vger.kernel.org
Signed-off-by: Ciro Iriarte <ciro.iriarte+software@gmail.com>
---
drivers/target/target_core_fabric_lib.c | 8 +++---
drivers/target/target_core_pr.c | 33 ++++++++++++++++++++++---
drivers/target/target_core_pr.h | 1 +
drivers/target/target_core_transport.c | 2 +-
4 files changed, 36 insertions(+), 8 deletions(-)
diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c
index ad024009d..f720fbce1 100644
--- a/drivers/target/target_core_fabric_lib.c
+++ b/drivers/target/target_core_fabric_lib.c
@@ -372,10 +372,10 @@ static bool iscsi_parse_pr_out_transport_id(
return false;
}
/*
- * The registration code reads the ISID as a C string,
- * and its first 8 bytes with get_unaligned_be64(), so
- * require 8 bytes after the separator and a NUL inside
- * the rest of the descriptor.
+ * The registration code reads the ISID as a C string, so
+ * require a NUL inside the rest of the descriptor, and at
+ * least 8 bytes after the separator: an ISID is twelve hex
+ * digits.
*/
if (buf + tid_len - p < 8 || !memchr(p, '\0', buf + tid_len - p)) {
pr_err("Incomplete or unterminated ISID in iSCSI Initiator port TransportID\n");
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index ca1a2802a..c59032228 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -19,6 +19,7 @@
#include <linux/fcntl.h>
#include <linux/fs.h>
#include <linux/fs_struct.h>
+#include <linux/hex.h>
#include <scsi/scsi_proto.h>
#include <linux/unaligned.h>
@@ -30,6 +31,28 @@
#include "target_core_pr.h"
#include "target_core_ua.h"
+/*
+ * lio_sess_get_initiator_sid() prints the six ISID bytes as twelve hex
+ * digits, and iSCSI TransportIDs carry the same digits. Convert all six
+ * bytes: reading the first eight digits as a big-endian u64 keeps only the
+ * first four ISID bytes, so two sessions of one initiator that differ only
+ * in the qualifier, the usual case, would compare equal. Text in any other
+ * format keeps the old conversion of its first eight characters, without
+ * reading past the end of a shorter string.
+ */
+u64 target_isid_to_bin(const char *isid)
+{
+ u8 bin[6];
+ char raw[8] = {};
+
+ if (strnlen(isid, 2 * sizeof(bin) + 1) == 2 * sizeof(bin) &&
+ !hex2bin(bin, isid, sizeof(bin)))
+ return get_unaligned_be48(bin);
+
+ memcpy(raw, isid, strnlen(isid, sizeof(raw)));
+ return get_unaligned_be64(raw);
+}
+
/*
* Used for Specify Initiator Ports Capable Bit (SPEC_I_PT)
*/
@@ -285,7 +308,11 @@ target_scsi2_reservation_reserve(struct se_cmd *cmd)
dev->reservation_holder = sess;
dev->dev_reservation_flags |= DRF_SPC2_RESERVATIONS;
- if (sess->sess_bin_isid != 0) {
+ /*
+ * An all-zero ISID converts to 0, so test whether the fabric has
+ * ISIDs rather than the value.
+ */
+ if (tpg->se_tpg_tfo->sess_get_initiator_sid) {
dev->dev_res_bin_isid = sess->sess_bin_isid;
dev->dev_reservation_flags |= DRF_SPC2_RESERVATIONS_WITH_ISID;
}
@@ -674,7 +701,7 @@ static struct t10_pr_registration *__core_scsi3_do_alloc_registration(
* save it to the registration now.
*/
if (isid != NULL) {
- pr_reg->pr_reg_bin_isid = get_unaligned_be64(isid);
+ pr_reg->pr_reg_bin_isid = target_isid_to_bin(isid);
snprintf(pr_reg->pr_reg_isid, PR_REG_ISID_LEN, "%s", isid);
pr_reg->isid_present_at_reg = 1;
}
@@ -866,7 +893,7 @@ int core_scsi3_alloc_aptpl_registration(
* SCSI Initiator Port, restore it now.
*/
if (isid != NULL) {
- pr_reg->pr_reg_bin_isid = get_unaligned_be64(isid);
+ pr_reg->pr_reg_bin_isid = target_isid_to_bin(isid);
snprintf(pr_reg->pr_reg_isid, PR_REG_ISID_LEN, "%s", isid);
pr_reg->isid_present_at_reg = 1;
}
diff --git a/drivers/target/target_core_pr.h b/drivers/target/target_core_pr.h
index b793c9963..4debfe4be 100644
--- a/drivers/target/target_core_pr.h
+++ b/drivers/target/target_core_pr.h
@@ -72,6 +72,7 @@ extern void core_scsi3_free_pr_reg_from_nacl(struct se_device *,
struct se_node_acl *);
extern void core_scsi3_free_all_registrations(struct se_device *);
extern unsigned char *core_scsi3_pr_dump_type(int);
+u64 target_isid_to_bin(const char *isid);
extern sense_reason_t target_scsi3_emulate_pr_in(struct se_cmd *);
extern sense_reason_t target_scsi3_emulate_pr_out(struct se_cmd *);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 927861c30..4629c9343 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -419,7 +419,7 @@ void __transport_register_session(
memset(&buf[0], 0, PR_REG_ISID_LEN);
se_tpg->se_tpg_tfo->sess_get_initiator_sid(se_sess,
&buf[0], PR_REG_ISID_LEN);
- se_sess->sess_bin_isid = get_unaligned_be64(&buf[0]);
+ se_sess->sess_bin_isid = target_isid_to_bin(buf);
}
spin_lock_irqsave(&se_nacl->nacl_sess_lock, flags);
--
2.55.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] scsi: target: compare all six ISID bytes when identifying a nexus
2026-11-09 13:12 [PATCH] scsi: target: compare all six ISID bytes when identifying a nexus Ciro Iriarte
@ 2026-11-09 13:30 ` sashiko-bot
2026-11-09 14:31 ` [PATCH v2] " Ciro Iriarte
1 sibling, 0 replies; 3+ messages in thread
From: sashiko-bot @ 2026-11-09 13:30 UTC (permalink / raw)
To: Ciro Iriarte; +Cc: target-devel, linux-scsi
Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [High] scsi: target: core_scsi3_pr_seq_non_holder() rejects registered
sessions
- [Low] scsi: target: inaccurate Fixes trailer for target_isid_to_bin()
changes
It also noticed 1 related pre-existing issue this patch does not
introduce:
- [Critical] scsi: target: unlocked list insertion in
core_scsi3_alloc_aptpl_registration() [1]
--
commit 3cb145890f871c3538fab6da7b3f3187cbc5c48e
Author: Ciro Iriarte <ciro.iriarte+software@gmail.com>
> scsi: target: compare all six ISID bytes when identifying a nexus
>
> lio_sess_get_initiator_sid() reports the ISID as twelve hex digits, and
> iSCSI TransportIDs carry the same digits. __transport_register_session(),
> __core_scsi3_do_alloc_registration() and
> core_scsi3_alloc_aptpl_registration() turn that text into
> sess_bin_isid and pr_reg_bin_isid with get_unaligned_be64(), which takes
> the first eight characters, i.e. the first four ISID bytes.
>
> open-iscsi ISIDs start with 00023d00 and differ only in the qualifier in
> the last two bytes, so every session of one initiator gets the same
> binary ISID. target_scsi2_reservation_check() and
> target_scsi3_pr_reservation_check() then treat any session of the
> reservation holder's initiator as the holder:
>
> - after RESERVE(6) on one session, another session of the same
> initiator can still write;
> - with a Write Exclusive persistent reservation, another session that
> is not registered, or registered but not the holder, can still write.
>
> Reproduced with two open-iscsi sessions (ifaces default and if2) to a
> ramdisk LUN: on v6.12.113 every command from the second session
> completes with GOOD; with this patch TEST UNIT READY and WRITE(10)
> under RESERVE(6), and WRITE(10) under Write Exclusive, return
> RESERVATION CONFLICT, and READ(10) is still allowed.
>
> Convert all six bytes. Text that is not exactly twelve hex digits keeps
> the old conversion of its first eight characters, now copied into a
> zeroed buffer so that a shorter string, such as an initiator_sid written
> to res_aptpl_metadata, is not read past its end.
>
> An all-zero ISID now converts to 0, which
> target_scsi2_reservation_reserve() took to mean "no ISID". Set
> DRF_SPC2_RESERVATIONS_WITH_ISID when the fabric reports ISIDs instead.
> Also update the TransportID parser comment that referred to the
> get_unaligned_be64() read.
>
> Initiators that relied on the old behaviour, reserving through one
> session and writing through another without registering it, will now
> see RESERVATION CONFLICT, as SPC requires.
>
> Fixes: e48354ce078c ("iscsi-target: Add iSCSI fabric support for target v4.1")
> Cc: stable@vger.kernel.org
> Signed-off-by: Ciro Iriarte <ciro.iriarte+software@gmail.com>
[Severity: Low]
e48354ce078c ("iscsi-target: Add iSCSI fabric support for target v4.1")
added drivers/target/iscsi/ and did not touch any of these files. The
get_unaligned_be64() ISID conversion and sess_bin_isid checks in target
core were introduced in c66ac9db8d4a ("[SCSI] target: Add LIO target core
v4.0.0-rc6").
[ ... ]
> diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
> index ca1a2802aa228..c59032228f3ab 100644
> --- a/drivers/target/target_core_pr.c
> +++ b/drivers/target/target_core_pr.c
> @@ -19,6 +19,7 @@
> #include <linux/fcntl.h>
> #include <linux/fs.h>
> #include <linux/fs_struct.h>
> +#include <linux/hex.h>
> #include <scsi/scsi_proto.h>
> #include <linux/unaligned.h>
>
> @@ -30,6 +31,28 @@
> #include "target_core_pr.h"
> #include "target_core_ua.h"
>
> +/*
> + * lio_sess_get_initiator_sid() prints the six ISID bytes as twelve hex
> + * digits, and iSCSI TransportIDs carry the same digits. Convert all six
> + * bytes: reading the first eight digits as a big-endian u64 keeps only the
> + * first four ISID bytes, so two sessions of one initiator that differ only
> + * in the qualifier, the usual case, would compare equal. Text in any other
> + * format keeps the old conversion of its first eight characters, without
> + * reading past the end of a shorter string.
> + */
> +u64 target_isid_to_bin(const char *isid)
> +{
> + u8 bin[6];
> + char raw[8] = {};
> +
> + if (strnlen(isid, 2 * sizeof(bin) + 1) == 2 * sizeof(bin) &&
> + !hex2bin(bin, isid, sizeof(bin)))
> + return get_unaligned_be48(bin);
> +
> + memcpy(raw, isid, strnlen(isid, sizeof(raw)));
> + return get_unaligned_be64(raw);
> +}
[Severity: High]
Does converting all six ISID bytes here cause
core_scsi3_pr_seq_non_holder() to treat other registered sessions of the
reservation holder's initiator as unregistered?
When an initiator opens two iSCSI sessions with different ISID qualifiers,
registers both, and acquires a persistent reservation on the first
session, a command on the second session reaches
target_scsi3_pr_reservation_check() with pr_reg_nacl == sess->se_node_acl
and pr_reg_bin_isid != sess->sess_bin_isid:
drivers/target/target_core_pr.c:target_scsi3_pr_reservation_check() {
...
if (dev->dev_pr_res_holder->isid_present_at_reg) {
if (dev->dev_pr_res_holder->pr_reg_bin_isid !=
sess->sess_bin_isid) {
isid_mismatch = true;
goto check_nonholder;
}
}
...
}
drivers/target/target_core_pr.c:core_scsi3_pr_seq_non_holder() {
...
if (isid_mismatch) {
registered_nexus = 0;
} else {
struct se_dev_entry *se_deve;
rcu_read_lock();
se_deve = target_nacl_find_deve(nacl, cmd->orig_fe_lun);
if (se_deve)
registered_nexus = test_bit(DEF_PR_REG_ACTIVE,
&se_deve->deve_flags);
rcu_read_unlock();
}
...
}
Because DEF_PR_REG_ACTIVE is tracked per se_dev_entry (shared across all
sessions of the initiator) rather than per session, the isid_mismatch
branch unconditionally forces registered_nexus = 0 instead of checking
whether cmd->se_sess has its own registration in
dev->t10_pr.registration_list. In a multipath setup where both sessions
are registered, writes on the second session under Registrants Only or All
Registrants reservations (as well as PREEMPT, CLEAR, or RELEASE from that
session) will now fail with TCM_RESERVATION_CONFLICT.
[ ... ]
> @@ -866,7 +893,7 @@ int core_scsi3_alloc_aptpl_registration(
> * SCSI Initiator Port, restore it now.
> */
> if (isid != NULL) {
> - pr_reg->pr_reg_bin_isid = get_unaligned_be64(isid);
> + pr_reg->pr_reg_bin_isid = target_isid_to_bin(isid);
> snprintf(pr_reg->pr_reg_isid, PR_REG_ISID_LEN, "%s", isid);
> pr_reg->isid_present_at_reg = 1;
> }
[Severity: Critical]
This problem wasn't introduced by this patch, but can
core_scsi3_alloc_aptpl_registration() corrupt pr_tmpl->aptpl_reg_list
[1] by calling list_add_tail() without holding
pr_tmpl->aptpl_reg_lock?
target_pr_res_aptpl_metadata_store() calls
core_scsi3_alloc_aptpl_registration() without taking aptpl_reg_lock:
CPU0 CPU1
target_pr_res_aptpl_metadata_store() __core_scsi3_check_aptpl_registration()
core_scsi3_alloc_aptpl_registration() spin_lock(&pr_tmpl->aptpl_reg_lock)
list_add_tail(..., list_del(&pr_reg->pr_reg_aptpl_list)
&pr_tmpl->aptpl_reg_list) <-- list corruption / use-after-free
Concurrent configfs writes through separate file descriptors, or a
configfs write racing with LUN export in
__core_scsi3_check_aptpl_registration() or teardown in
core_scsi3_free_all_registrations(), manipulate pr_tmpl->aptpl_reg_list at
the same time and can corrupt the list.
[1] https://sashiko.dev/#/bug/linux-620bb3ae-6c71-4e47-b64f-f502f2ef27c0
--
Sashiko AI review · https://sashiko.dev/#/patchset/591ac67a-fa1e-4395-9573-2d9405cfe0b6@gmail.com?part=1
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v2] scsi: target: compare all six ISID bytes when identifying a nexus
2026-11-09 13:12 [PATCH] scsi: target: compare all six ISID bytes when identifying a nexus Ciro Iriarte
2026-11-09 13:30 ` sashiko-bot
@ 2026-11-09 14:31 ` Ciro Iriarte
1 sibling, 0 replies; 3+ messages in thread
From: Ciro Iriarte @ 2026-11-09 14:31 UTC (permalink / raw)
To: Martin K. Petersen; +Cc: target-devel, linux-scsi, linux-kernel, stable
lio_sess_get_initiator_sid() reports the ISID as twelve hex digits, and
iSCSI TransportIDs carry the same digits. __transport_register_session(),
__core_scsi3_do_alloc_registration() and
core_scsi3_alloc_aptpl_registration() turn that text into
sess_bin_isid and pr_reg_bin_isid with get_unaligned_be64(), which takes
the first eight characters, i.e. the first four ISID bytes.
open-iscsi ISIDs start with 00023d00 and differ only in the qualifier in
the last two bytes, so every session of one initiator gets the same
binary ISID. target_scsi2_reservation_check() and
target_scsi3_pr_reservation_check() then treat any session of the
reservation holder's initiator as the holder:
- after RESERVE(6) on one session, another session of the same
initiator can still write;
- with a Write Exclusive persistent reservation, another session that
is not registered, or registered but not the holder, can still write.
Reproduced with two open-iscsi sessions (ifaces default and if2) to a
ramdisk LUN: on v6.12.113 every TEST UNIT READY, READ(10) and WRITE(10)
the test sent from the second session completed with GOOD, under
RESERVE(6) and under each persistent reservation type, whether or not
that session was registered.
Convert all six bytes. Text that is not exactly twelve hex digits keeps
the old conversion of its first eight characters, now copied into a
zeroed buffer so that a shorter string, such as an initiator_sid written
to res_aptpl_metadata, is not read past its end.
An all-zero ISID now converts to 0, which
target_scsi2_reservation_reserve() took to mean "no ISID". Set
DRF_SPC2_RESERVATIONS_WITH_ISID when the fabric reports ISIDs instead.
Also update the TransportID parser comment that referred to the
get_unaligned_be64() read.
With distinct ISIDs, target_scsi3_pr_reservation_check() now sets
isid_mismatch for the holder initiator's other sessions, and
core_scsi3_pr_seq_non_holder() treated every such session as
unregistered: DEF_PR_REG_ACTIVE is kept per se_dev_entry, which all
sessions of the initiator share, so it cannot tell them apart. A
session that registered its own key would then get RESERVATION
CONFLICT for writes under a Registrants Only or All Registrants
reservation, and for PREEMPT, CLEAR and RELEASE. Look up that session's
own registration with core_scsi3_locate_pr_reg() instead.
With this patch, TEST UNIT READY and WRITE(10) from the second session
under RESERVE(6) return RESERVATION CONFLICT. Under Write Exclusive,
WRITE(10) from the second session conflicts whether or not it is
registered, and READ(10) is allowed. Under the Registrants Only and All
Registrants types, WRITE(10) from the second session conflicts until it
registers, as does READ(10) under the Exclusive Access types; once
registered it has access and can PREEMPT the holder.
Initiators that relied on the old behaviour, reserving through one
session and writing through another without registering it, will now
see RESERVATION CONFLICT, as SPC requires.
Fixes: c66ac9db8d4a ("[SCSI] target: Add LIO target core v4.0.0-rc6")
Cc: stable@vger.kernel.org
Signed-off-by: Ciro Iriarte <ciro.iriarte+software@gmail.com>
---
v2:
- core_scsi3_pr_seq_non_holder(): on an ISID mismatch, look up the
session's own registration instead of treating it as unregistered.
v1 made that path reachable for the holder initiator's other sessions,
so a registered second session got RESERVATION CONFLICT under the
Registrants Only / All Registrants types and for PREEMPT, CLEAR and
RELEASE (Sashiko review). Re-tested on v6.12.113 with types 1, 5-8
and PREEMPT/RELEASE/CLEAR from the second session.
- Fixes: now points at c66ac9db8d4a, which added the get_unaligned_be64()
conversion; e48354ce078c only made it reachable (Sashiko review).
- Reworded the TransportID parser comment.
v1: https://lore.kernel.org/r/591ac67a-fa1e-4395-9573-2d9405cfe0b6@gmail.com
drivers/target/target_core_fabric_lib.c | 9 ++---
drivers/target/target_core_pr.c | 46 ++++++++++++++++++++++---
drivers/target/target_core_pr.h | 1 +
drivers/target/target_core_transport.c | 2 +-
4 files changed, 49 insertions(+), 9 deletions(-)
diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c
index ad024009d..ccfeba645 100644
--- a/drivers/target/target_core_fabric_lib.c
+++ b/drivers/target/target_core_fabric_lib.c
@@ -372,10 +372,11 @@ static bool iscsi_parse_pr_out_transport_id(
return false;
}
/*
- * The registration code reads the ISID as a C string,
- * and its first 8 bytes with get_unaligned_be64(), so
- * require 8 bytes after the separator and a NUL inside
- * the rest of the descriptor.
+ * The registration code reads the ISID as a C string, so
+ * require a NUL inside the rest of the descriptor. Keep the
+ * existing minimum of 8 bytes after the separator: a valid
+ * ISID is twelve hex digits, and target_isid_to_bin() falls
+ * back to the first eight characters of anything else.
*/
if (buf + tid_len - p < 8 || !memchr(p, '\0', buf + tid_len - p)) {
pr_err("Incomplete or unterminated ISID in iSCSI Initiator port TransportID\n");
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index ca1a2802a..0f2ff9d42 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -19,6 +19,7 @@
#include <linux/fcntl.h>
#include <linux/fs.h>
#include <linux/fs_struct.h>
+#include <linux/hex.h>
#include <scsi/scsi_proto.h>
#include <linux/unaligned.h>
@@ -30,6 +31,28 @@
#include "target_core_pr.h"
#include "target_core_ua.h"
+/*
+ * lio_sess_get_initiator_sid() prints the six ISID bytes as twelve hex
+ * digits, and iSCSI TransportIDs carry the same digits. Convert all six
+ * bytes: reading the first eight digits as a big-endian u64 keeps only the
+ * first four ISID bytes, so two sessions of one initiator that differ only
+ * in the qualifier, the usual case, would compare equal. Text in any other
+ * format keeps the old conversion of its first eight characters, without
+ * reading past the end of a shorter string.
+ */
+u64 target_isid_to_bin(const char *isid)
+{
+ u8 bin[6];
+ char raw[8] = {};
+
+ if (strnlen(isid, 2 * sizeof(bin) + 1) == 2 * sizeof(bin) &&
+ !hex2bin(bin, isid, sizeof(bin)))
+ return get_unaligned_be48(bin);
+
+ memcpy(raw, isid, strnlen(isid, sizeof(raw)));
+ return get_unaligned_be64(raw);
+}
+
/*
* Used for Specify Initiator Ports Capable Bit (SPEC_I_PT)
*/
@@ -285,7 +308,11 @@ target_scsi2_reservation_reserve(struct se_cmd *cmd)
dev->reservation_holder = sess;
dev->dev_reservation_flags |= DRF_SPC2_RESERVATIONS;
- if (sess->sess_bin_isid != 0) {
+ /*
+ * An all-zero ISID converts to 0, so test whether the fabric has
+ * ISIDs rather than the value.
+ */
+ if (tpg->se_tpg_tfo->sess_get_initiator_sid) {
dev->dev_res_bin_isid = sess->sess_bin_isid;
dev->dev_reservation_flags |= DRF_SPC2_RESERVATIONS_WITH_ISID;
}
@@ -323,7 +350,18 @@ static int core_scsi3_pr_seq_non_holder(struct se_cmd *cmd, u32 pr_reg_type,
* RESERVATION CONFLICT on some CDBs */
if (isid_mismatch) {
- registered_nexus = 0;
+ struct t10_pr_registration *pr_reg;
+
+ /*
+ * Another I_T nexus of the holder's initiator. DEF_PR_REG_ACTIVE
+ * is shared by all of its sessions, so look for a registration
+ * made through this one.
+ */
+ pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, nacl, se_sess);
+ if (pr_reg) {
+ registered_nexus = 1;
+ core_scsi3_put_pr_reg(pr_reg);
+ }
} else {
struct se_dev_entry *se_deve;
@@ -674,7 +712,7 @@ static struct t10_pr_registration *__core_scsi3_do_alloc_registration(
* save it to the registration now.
*/
if (isid != NULL) {
- pr_reg->pr_reg_bin_isid = get_unaligned_be64(isid);
+ pr_reg->pr_reg_bin_isid = target_isid_to_bin(isid);
snprintf(pr_reg->pr_reg_isid, PR_REG_ISID_LEN, "%s", isid);
pr_reg->isid_present_at_reg = 1;
}
@@ -866,7 +904,7 @@ int core_scsi3_alloc_aptpl_registration(
* SCSI Initiator Port, restore it now.
*/
if (isid != NULL) {
- pr_reg->pr_reg_bin_isid = get_unaligned_be64(isid);
+ pr_reg->pr_reg_bin_isid = target_isid_to_bin(isid);
snprintf(pr_reg->pr_reg_isid, PR_REG_ISID_LEN, "%s", isid);
pr_reg->isid_present_at_reg = 1;
}
diff --git a/drivers/target/target_core_pr.h b/drivers/target/target_core_pr.h
index b793c9963..4debfe4be 100644
--- a/drivers/target/target_core_pr.h
+++ b/drivers/target/target_core_pr.h
@@ -72,6 +72,7 @@ extern void core_scsi3_free_pr_reg_from_nacl(struct se_device *,
struct se_node_acl *);
extern void core_scsi3_free_all_registrations(struct se_device *);
extern unsigned char *core_scsi3_pr_dump_type(int);
+u64 target_isid_to_bin(const char *isid);
extern sense_reason_t target_scsi3_emulate_pr_in(struct se_cmd *);
extern sense_reason_t target_scsi3_emulate_pr_out(struct se_cmd *);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 927861c30..4629c9343 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -419,7 +419,7 @@ void __transport_register_session(
memset(&buf[0], 0, PR_REG_ISID_LEN);
se_tpg->se_tpg_tfo->sess_get_initiator_sid(se_sess,
&buf[0], PR_REG_ISID_LEN);
- se_sess->sess_bin_isid = get_unaligned_be64(&buf[0]);
+ se_sess->sess_bin_isid = target_isid_to_bin(buf);
}
spin_lock_irqsave(&se_nacl->nacl_sess_lock, flags);
--
2.55.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-11-09 14:57 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-09 13:12 [PATCH] scsi: target: compare all six ISID bytes when identifying a nexus Ciro Iriarte
2026-11-09 13:30 ` sashiko-bot
2026-11-09 14:31 ` [PATCH v2] " Ciro Iriarte
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox