Skip to content

Commit 6e0f6aa

Browse files
maurizio-lombardimartinkpetersen
authored andcommitted
scsi: target: core: Generate correct identifiers for PR OUT transport IDs
Fix target_parse_pr_out_transport_id() to return a string representing the transport ID in a human-readable format (e.g., naa.xxxxxxxx...) for various SCSI protocol types (SAS, FCP, SRP, SBP). Previously, the function returned a pointer to the raw binary buffer, which was incorrectly compared against human-readable strings, causing comparisons to fail. Now, the function writes a properly formatted string into a buffer provided by the caller. The output format depends on the transport protocol: * SAS: 64-bit identifier, "naa." prefix. * FCP: 64-bit identifier, colon separated values. * SBP: 64-bit identifier, no prefix. * SRP: 128-bit identifier, "0x" prefix. * iSCSI: IQN string. Signed-off-by: Maurizio Lombardi <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Dmitry Bogdanov <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 220e608 commit 6e0f6aa

File tree

3 files changed

+60
-25
lines changed

3 files changed

+60
-25
lines changed

drivers/target/target_core_fabric_lib.c

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -257,11 +257,41 @@ static int iscsi_get_pr_transport_id_len(
257257
return len;
258258
}
259259

260-
static char *iscsi_parse_pr_out_transport_id(
260+
static void sas_parse_pr_out_transport_id(char *buf, char *i_str)
261+
{
262+
char hex[17] = {};
263+
264+
bin2hex(hex, buf + 4, 8);
265+
snprintf(i_str, TRANSPORT_IQN_LEN, "naa.%s", hex);
266+
}
267+
268+
static void srp_parse_pr_out_transport_id(char *buf, char *i_str)
269+
{
270+
char hex[33] = {};
271+
272+
bin2hex(hex, buf + 8, 16);
273+
snprintf(i_str, TRANSPORT_IQN_LEN, "0x%s", hex);
274+
}
275+
276+
static void fcp_parse_pr_out_transport_id(char *buf, char *i_str)
277+
{
278+
snprintf(i_str, TRANSPORT_IQN_LEN, "%8phC", buf + 8);
279+
}
280+
281+
static void sbp_parse_pr_out_transport_id(char *buf, char *i_str)
282+
{
283+
char hex[17] = {};
284+
285+
bin2hex(hex, buf + 8, 8);
286+
snprintf(i_str, TRANSPORT_IQN_LEN, "%s", hex);
287+
}
288+
289+
static bool iscsi_parse_pr_out_transport_id(
261290
struct se_portal_group *se_tpg,
262291
char *buf,
263292
u32 *out_tid_len,
264-
char **port_nexus_ptr)
293+
char **port_nexus_ptr,
294+
char *i_str)
265295
{
266296
char *p;
267297
int i;
@@ -282,7 +312,7 @@ static char *iscsi_parse_pr_out_transport_id(
282312
if ((format_code != 0x00) && (format_code != 0x40)) {
283313
pr_err("Illegal format code: 0x%02x for iSCSI"
284314
" Initiator Transport ID\n", format_code);
285-
return NULL;
315+
return false;
286316
}
287317
/*
288318
* If the caller wants the TransportID Length, we set that value for the
@@ -306,7 +336,7 @@ static char *iscsi_parse_pr_out_transport_id(
306336
pr_err("Unable to locate \",i,0x\" separator"
307337
" for Initiator port identifier: %s\n",
308338
&buf[4]);
309-
return NULL;
339+
return false;
310340
}
311341
*p = '\0'; /* Terminate iSCSI Name */
312342
p += 5; /* Skip over ",i,0x" separator */
@@ -339,7 +369,8 @@ static char *iscsi_parse_pr_out_transport_id(
339369
} else
340370
*port_nexus_ptr = NULL;
341371

342-
return &buf[4];
372+
strscpy(i_str, &buf[4], TRANSPORT_IQN_LEN);
373+
return true;
343374
}
344375

345376
int target_get_pr_transport_id_len(struct se_node_acl *nacl,
@@ -387,33 +418,35 @@ int target_get_pr_transport_id(struct se_node_acl *nacl,
387418
}
388419
}
389420

390-
const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
391-
char *buf, u32 *out_tid_len, char **port_nexus_ptr)
421+
bool target_parse_pr_out_transport_id(struct se_portal_group *tpg,
422+
char *buf, u32 *out_tid_len, char **port_nexus_ptr, char *i_str)
392423
{
393-
u32 offset;
394-
395424
switch (tpg->proto_id) {
396425
case SCSI_PROTOCOL_SAS:
397426
/*
398427
* Assume the FORMAT CODE 00b from spc4r17, 7.5.4.7 TransportID
399428
* for initiator ports using SCSI over SAS Serial SCSI Protocol.
400429
*/
401-
offset = 4;
430+
sas_parse_pr_out_transport_id(buf, i_str);
402431
break;
403-
case SCSI_PROTOCOL_SBP:
404432
case SCSI_PROTOCOL_SRP:
433+
srp_parse_pr_out_transport_id(buf, i_str);
434+
break;
405435
case SCSI_PROTOCOL_FCP:
406-
offset = 8;
436+
fcp_parse_pr_out_transport_id(buf, i_str);
437+
break;
438+
case SCSI_PROTOCOL_SBP:
439+
sbp_parse_pr_out_transport_id(buf, i_str);
407440
break;
408441
case SCSI_PROTOCOL_ISCSI:
409442
return iscsi_parse_pr_out_transport_id(tpg, buf, out_tid_len,
410-
port_nexus_ptr);
443+
port_nexus_ptr, i_str);
411444
default:
412445
pr_err("Unknown proto_id: 0x%02x\n", tpg->proto_id);
413-
return NULL;
446+
return false;
414447
}
415448

416449
*port_nexus_ptr = NULL;
417450
*out_tid_len = 24;
418-
return buf + offset;
451+
return true;
419452
}

drivers/target/target_core_internal.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ int target_get_pr_transport_id_len(struct se_node_acl *nacl,
103103
int target_get_pr_transport_id(struct se_node_acl *nacl,
104104
struct t10_pr_registration *pr_reg, int *format_code,
105105
unsigned char *buf);
106-
const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
107-
char *buf, u32 *out_tid_len, char **port_nexus_ptr);
106+
bool target_parse_pr_out_transport_id(struct se_portal_group *tpg,
107+
char *buf, u32 *out_tid_len, char **port_nexus_ptr, char *i_str);
108108

109109
/* target_core_hba.c */
110110
struct se_hba *core_alloc_hba(const char *, u32, u32);

drivers/target/target_core_pr.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,11 +1478,12 @@ core_scsi3_decode_spec_i_port(
14781478
LIST_HEAD(tid_dest_list);
14791479
struct pr_transport_id_holder *tidh_new, *tidh, *tidh_tmp;
14801480
unsigned char *buf, *ptr, proto_ident;
1481-
const unsigned char *i_str = NULL;
1481+
unsigned char i_str[TRANSPORT_IQN_LEN];
14821482
char *iport_ptr = NULL, i_buf[PR_REG_ISID_ID_LEN];
14831483
sense_reason_t ret;
14841484
u32 tpdl, tid_len = 0;
14851485
u32 dest_rtpi = 0;
1486+
bool tid_found;
14861487

14871488
/*
14881489
* Allocate a struct pr_transport_id_holder and setup the
@@ -1571,9 +1572,9 @@ core_scsi3_decode_spec_i_port(
15711572
dest_rtpi = tmp_lun->lun_tpg->tpg_rtpi;
15721573

15731574
iport_ptr = NULL;
1574-
i_str = target_parse_pr_out_transport_id(tmp_tpg,
1575-
ptr, &tid_len, &iport_ptr);
1576-
if (!i_str)
1575+
tid_found = target_parse_pr_out_transport_id(tmp_tpg,
1576+
ptr, &tid_len, &iport_ptr, i_str);
1577+
if (!tid_found)
15771578
continue;
15781579
/*
15791580
* Determine if this SCSI device server requires that
@@ -3151,13 +3152,14 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key,
31513152
struct t10_pr_registration *pr_reg, *pr_res_holder, *dest_pr_reg;
31523153
struct t10_reservation *pr_tmpl = &dev->t10_pr;
31533154
unsigned char *buf;
3154-
const unsigned char *initiator_str;
3155+
unsigned char initiator_str[TRANSPORT_IQN_LEN];
31553156
char *iport_ptr = NULL, i_buf[PR_REG_ISID_ID_LEN] = { };
31563157
u32 tid_len, tmp_tid_len;
31573158
int new_reg = 0, type, scope, matching_iname;
31583159
sense_reason_t ret;
31593160
unsigned short rtpi;
31603161
unsigned char proto_ident;
3162+
bool tid_found;
31613163

31623164
if (!se_sess || !se_lun) {
31633165
pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
@@ -3276,9 +3278,9 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key,
32763278
ret = TCM_INVALID_PARAMETER_LIST;
32773279
goto out;
32783280
}
3279-
initiator_str = target_parse_pr_out_transport_id(dest_se_tpg,
3280-
&buf[24], &tmp_tid_len, &iport_ptr);
3281-
if (!initiator_str) {
3281+
tid_found = target_parse_pr_out_transport_id(dest_se_tpg,
3282+
&buf[24], &tmp_tid_len, &iport_ptr, initiator_str);
3283+
if (!tid_found) {
32823284
pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate"
32833285
" initiator_str from Transport ID\n");
32843286
ret = TCM_INVALID_PARAMETER_LIST;

0 commit comments

Comments
 (0)