Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <mlombard@redhat.com>
Link: https://lore.kernel.org/r/20250714133738.11054-1-mlombard@redhat.com
Reviewed-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Maurizio Lombardi and committed by
Martin K. Petersen
6e0f6aa4 220e6083

+61 -26
+49 -16
drivers/target/target_core_fabric_lib.c
··· 257 257 return len; 258 258 } 259 259 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( 261 290 struct se_portal_group *se_tpg, 262 291 char *buf, 263 292 u32 *out_tid_len, 264 - char **port_nexus_ptr) 293 + char **port_nexus_ptr, 294 + char *i_str) 265 295 { 266 296 char *p; 267 297 int i; ··· 312 282 if ((format_code != 0x00) && (format_code != 0x40)) { 313 283 pr_err("Illegal format code: 0x%02x for iSCSI" 314 284 " Initiator Transport ID\n", format_code); 315 - return NULL; 285 + return false; 316 286 } 317 287 /* 318 288 * If the caller wants the TransportID Length, we set that value for the ··· 336 306 pr_err("Unable to locate \",i,0x\" separator" 337 307 " for Initiator port identifier: %s\n", 338 308 &buf[4]); 339 - return NULL; 309 + return false; 340 310 } 341 311 *p = '\0'; /* Terminate iSCSI Name */ 342 312 p += 5; /* Skip over ",i,0x" separator */ ··· 369 339 } else 370 340 *port_nexus_ptr = NULL; 371 341 372 - return &buf[4]; 342 + strscpy(i_str, &buf[4], TRANSPORT_IQN_LEN); 343 + return true; 373 344 } 374 345 375 346 int target_get_pr_transport_id_len(struct se_node_acl *nacl, ··· 418 387 } 419 388 } 420 389 421 - const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg, 422 - char *buf, u32 *out_tid_len, char **port_nexus_ptr) 390 + bool target_parse_pr_out_transport_id(struct se_portal_group *tpg, 391 + char *buf, u32 *out_tid_len, char **port_nexus_ptr, char *i_str) 423 392 { 424 - u32 offset; 425 - 426 393 switch (tpg->proto_id) { 427 394 case SCSI_PROTOCOL_SAS: 428 395 /* 429 396 * Assume the FORMAT CODE 00b from spc4r17, 7.5.4.7 TransportID 430 397 * for initiator ports using SCSI over SAS Serial SCSI Protocol. 431 398 */ 432 - offset = 4; 399 + sas_parse_pr_out_transport_id(buf, i_str); 400 + break; 401 + case SCSI_PROTOCOL_SRP: 402 + srp_parse_pr_out_transport_id(buf, i_str); 403 + break; 404 + case SCSI_PROTOCOL_FCP: 405 + fcp_parse_pr_out_transport_id(buf, i_str); 433 406 break; 434 407 case SCSI_PROTOCOL_SBP: 435 - case SCSI_PROTOCOL_SRP: 436 - case SCSI_PROTOCOL_FCP: 437 - offset = 8; 408 + sbp_parse_pr_out_transport_id(buf, i_str); 438 409 break; 439 410 case SCSI_PROTOCOL_ISCSI: 440 411 return iscsi_parse_pr_out_transport_id(tpg, buf, out_tid_len, 441 - port_nexus_ptr); 412 + port_nexus_ptr, i_str); 442 413 default: 443 414 pr_err("Unknown proto_id: 0x%02x\n", tpg->proto_id); 444 - return NULL; 415 + return false; 445 416 } 446 417 447 418 *port_nexus_ptr = NULL; 448 419 *out_tid_len = 24; 449 - return buf + offset; 420 + return true; 450 421 }
+2 -2
drivers/target/target_core_internal.h
··· 103 103 int target_get_pr_transport_id(struct se_node_acl *nacl, 104 104 struct t10_pr_registration *pr_reg, int *format_code, 105 105 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); 108 108 109 109 /* target_core_hba.c */ 110 110 struct se_hba *core_alloc_hba(const char *, u32, u32);
+10 -8
drivers/target/target_core_pr.c
··· 1478 1478 LIST_HEAD(tid_dest_list); 1479 1479 struct pr_transport_id_holder *tidh_new, *tidh, *tidh_tmp; 1480 1480 unsigned char *buf, *ptr, proto_ident; 1481 - const unsigned char *i_str = NULL; 1481 + unsigned char i_str[TRANSPORT_IQN_LEN]; 1482 1482 char *iport_ptr = NULL, i_buf[PR_REG_ISID_ID_LEN]; 1483 1483 sense_reason_t ret; 1484 1484 u32 tpdl, tid_len = 0; 1485 1485 u32 dest_rtpi = 0; 1486 + bool tid_found; 1486 1487 1487 1488 /* 1488 1489 * Allocate a struct pr_transport_id_holder and setup the ··· 1572 1571 dest_rtpi = tmp_lun->lun_tpg->tpg_rtpi; 1573 1572 1574 1573 iport_ptr = NULL; 1575 - i_str = target_parse_pr_out_transport_id(tmp_tpg, 1576 - ptr, &tid_len, &iport_ptr); 1577 - if (!i_str) 1574 + tid_found = target_parse_pr_out_transport_id(tmp_tpg, 1575 + ptr, &tid_len, &iport_ptr, i_str); 1576 + if (!tid_found) 1578 1577 continue; 1579 1578 /* 1580 1579 * Determine if this SCSI device server requires that ··· 3152 3151 struct t10_pr_registration *pr_reg, *pr_res_holder, *dest_pr_reg; 3153 3152 struct t10_reservation *pr_tmpl = &dev->t10_pr; 3154 3153 unsigned char *buf; 3155 - const unsigned char *initiator_str; 3154 + unsigned char initiator_str[TRANSPORT_IQN_LEN]; 3156 3155 char *iport_ptr = NULL, i_buf[PR_REG_ISID_ID_LEN] = { }; 3157 3156 u32 tid_len, tmp_tid_len; 3158 3157 int new_reg = 0, type, scope, matching_iname; 3159 3158 sense_reason_t ret; 3160 3159 unsigned short rtpi; 3161 3160 unsigned char proto_ident; 3161 + bool tid_found; 3162 3162 3163 3163 if (!se_sess || !se_lun) { 3164 3164 pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); ··· 3278 3276 ret = TCM_INVALID_PARAMETER_LIST; 3279 3277 goto out; 3280 3278 } 3281 - initiator_str = target_parse_pr_out_transport_id(dest_se_tpg, 3282 - &buf[24], &tmp_tid_len, &iport_ptr); 3283 - if (!initiator_str) { 3279 + tid_found = target_parse_pr_out_transport_id(dest_se_tpg, 3280 + &buf[24], &tmp_tid_len, &iport_ptr, initiator_str); 3281 + if (!tid_found) { 3284 3282 pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" 3285 3283 " initiator_str from Transport ID\n"); 3286 3284 ret = TCM_INVALID_PARAMETER_LIST;