@@ -33,14 +33,14 @@
static int sas_get_pr_transport_id(
- struct t10_pr_registration *pr_reg,
- int *format_code,
+ const char *initiatorname,
unsigned char *buf)
{
int ret;
+ buf[0] = SCSI_PROTOCOL_SAS;
/* Skip over 'naa. prefix */
- ret = hex2bin(&buf[4], &pr_reg->pr_iport[4], 8);
+ ret = hex2bin(&buf[4], &initiatorname[4], 8);
if (ret) {
pr_debug("%s: invalid hex string\n", __func__);
return ret;
@@ -50,19 +50,19 @@ static int sas_get_pr_transport_id(
}
static int fc_get_pr_transport_id(
- struct t10_pr_registration *pr_reg,
- int *format_code,
+ const char *initiatorname,
unsigned char *buf)
{
- unsigned char *ptr;
+ const char *ptr;
int i, ret;
u32 off = 8;
+ buf[0] = SCSI_PROTOCOL_FCP;
/*
* We convert the ASCII formatted N Port name into a binary
* encoded TransportID.
*/
- ptr = &pr_reg->pr_iport[0];
+ ptr = &initiatorname[0];
for (i = 0; i < 23; ) {
if (!strncmp(&ptr[i], ":", 1)) {
i++;
@@ -82,13 +82,14 @@ static int fc_get_pr_transport_id(
}
static int sbp_get_pr_transport_id(
- struct t10_pr_registration *pr_reg,
- int *format_code,
+ const char *initiatorname,
unsigned char *buf)
{
int ret;
- ret = hex2bin(&buf[8], pr_reg->pr_iport, 8);
+ buf[0] = SCSI_PROTOCOL_SBP;
+
+ ret = hex2bin(&buf[8], initiatorname, 8);
if (ret) {
pr_debug("%s: invalid hex string\n", __func__);
return ret;
@@ -98,15 +99,16 @@ static int sbp_get_pr_transport_id(
}
static int srp_get_pr_transport_id(
- struct t10_pr_registration *pr_reg,
- int *format_code,
+ const char *initiatorname,
unsigned char *buf)
{
const char *p;
unsigned len, count, leading_zero_bytes;
int rc;
- p = pr_reg->pr_iport;
+ buf[0] = SCSI_PROTOCOL_SRP;
+
+ p = initiatorname;
if (strncasecmp(p, "0x", 2) == 0)
p += 2;
len = strlen(p);
@@ -126,14 +128,16 @@ static int srp_get_pr_transport_id(
}
static int iscsi_get_pr_transport_id(
- struct t10_pr_registration *pr_reg,
- int *format_code,
+ const char *initiatorname,
+ unsigned char *isid,
unsigned char *buf)
{
u32 off = 4, padding = 0;
int isid_len;
u16 len = 0;
+ buf[0] = SCSI_PROTOCOL_ISCSI;
+
/*
* Only null terminate the last field.
*
@@ -149,9 +153,9 @@ static int iscsi_get_pr_transport_id(
* length of the iSCSI TransportID or the contents of the ADDITIONAL
* LENGTH field.
*/
- len = sprintf(&buf[off], "%s", pr_reg->pr_iport);
+ len = sprintf(&buf[off], "%s", initiatorname);
off += len;
- if ((*format_code == 1) && (pr_reg->isid_present_at_reg)) {
+ if (isid) {
/*
* Set FORMAT CODE 01b for iSCSI Initiator port TransportID
* format.
@@ -185,7 +189,7 @@ static int iscsi_get_pr_transport_id(
buf[off++] = 0x78; /* ASCII Character: "x" */
len += 5;
- isid_len = sprintf(buf + off, "%s", pr_reg->pr_reg_isid);
+ isid_len = sprintf(buf + off, "%s", isid);
off += isid_len;
len += isid_len;
}
@@ -210,47 +214,6 @@ static int iscsi_get_pr_transport_id(
return len;
}
-static int iscsi_get_pr_transport_id_len(
- struct t10_pr_registration *pr_reg,
- int *format_code)
-{
- u32 len = 0, padding = 0;
-
- len = strlen(pr_reg->pr_iport);
- /*
- * Add extra byte for NULL terminator
- */
- len++;
- /*
- * If there is ISID present with the registration, use format code:
- * 01b: iSCSI Initiator port TransportID format
- *
- * If there is not an active iSCSI session, use format code:
- * 00b: iSCSI Initiator device TransportID format
- */
- if (pr_reg->isid_present_at_reg) {
- len += 5; /* For ",i,0x" ASCII separator */
- len += strlen(pr_reg->pr_reg_isid);
- *format_code = 1;
- } else
- *format_code = 0;
- /*
- * The ADDITIONAL LENGTH field specifies the number of bytes that follow
- * in the TransportID. The additional length shall be at least 20 and
- * shall be a multiple of four.
- */
- padding = ((-len) & 3);
- if (padding != 0)
- len += padding;
- /*
- * Increment value for total payload + header length for
- * full status descriptor
- */
- len += 4;
-
- return len;
-}
-
static char *iscsi_parse_pr_out_transport_id(
struct se_portal_group *se_tpg,
char *buf,
@@ -336,47 +299,54 @@ static char *iscsi_parse_pr_out_transport_id(
return &buf[4];
}
-int target_get_pr_transport_id_len(
- struct t10_pr_registration *pr_reg, int *format_code)
+int target_get_pr_transport_id_len(struct t10_pr_registration *pr_reg)
{
- switch (pr_reg->se_tpg->proto_id) {
+ switch (pr_reg->pr_tid[0] & 0xF) {
case SCSI_PROTOCOL_FCP:
case SCSI_PROTOCOL_SBP:
case SCSI_PROTOCOL_SRP:
case SCSI_PROTOCOL_SAS:
- break;
+ return 24;
case SCSI_PROTOCOL_ISCSI:
- return iscsi_get_pr_transport_id_len(pr_reg, format_code);
+ return get_unaligned_be16(&pr_reg->pr_tid[2]) + 4;
default:
- pr_err("Unknown proto_id: 0x%02x\n", pr_reg->se_tpg->proto_id);
+ WARN(1, "Unknown proto_id: %#x\n", pr_reg->pr_tid[0] & 0xF);
return -EINVAL;
}
-
- /*
- * Most transports use a fixed length 24 byte identifier.
- */
- *format_code = 0;
- return 24;
}
int target_get_pr_transport_id(
- struct t10_pr_registration *pr_reg, int *format_code,
+ struct t10_pr_registration *pr_reg,
unsigned char *buf)
{
- switch (pr_reg->se_tpg->proto_id) {
+ int len = target_get_pr_transport_id_len(pr_reg);
+
+ if (len > 0)
+ memcpy(buf, pr_reg->pr_tid, len);
+
+ return len;
+}
+
+int target_gen_pr_transport_id(
+ struct t10_pr_registration *pr_reg,
+ int proto_id,
+ const char *initiatorname,
+ unsigned char *isid)
+{
+
+ switch (proto_id) {
case SCSI_PROTOCOL_SAS:
- return sas_get_pr_transport_id(pr_reg, format_code, buf);
+ return sas_get_pr_transport_id(initiatorname, pr_reg->pr_tid);
case SCSI_PROTOCOL_SBP:
- return sbp_get_pr_transport_id(pr_reg, format_code, buf);
+ return sbp_get_pr_transport_id(initiatorname, pr_reg->pr_tid);
case SCSI_PROTOCOL_SRP:
- return srp_get_pr_transport_id(pr_reg, format_code, buf);
+ return srp_get_pr_transport_id(initiatorname, pr_reg->pr_tid);
case SCSI_PROTOCOL_FCP:
- return fc_get_pr_transport_id(pr_reg, format_code, buf);
+ return fc_get_pr_transport_id(initiatorname, pr_reg->pr_tid);
case SCSI_PROTOCOL_ISCSI:
- return iscsi_get_pr_transport_id(pr_reg, format_code,
- buf);
+ return iscsi_get_pr_transport_id(initiatorname, isid, pr_reg->pr_tid);
default:
- pr_err("Unknown proto_id: 0x%02x\n", pr_reg->se_tpg->proto_id);
+ pr_err("Unknown proto_id: 0x%02x\n", proto_id);
return -EINVAL;
}
}
@@ -98,10 +98,13 @@ void target_setup_backend_cits(struct target_backend *);
int target_fabric_setup_cits(struct target_fabric_configfs *);
/* target_core_fabric_lib.c */
-int target_get_pr_transport_id_len(struct t10_pr_registration *pr_reg,
- int *format_code);
+int target_get_pr_transport_id_len(struct t10_pr_registration *pr_reg);
int target_get_pr_transport_id(struct t10_pr_registration *pr_reg,
- int *format_code, unsigned char *buf);
+ unsigned char *buf);
+int target_gen_pr_transport_id(struct t10_pr_registration *pr_reg,
+ int proto_id,
+ const char *initiatorname,
+ unsigned char *isid);
const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
char *buf, u32 *out_tid_len, char **port_nexus_ptr);
@@ -716,6 +716,10 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration(
aptpl);
if (!pr_reg)
return NULL;
+
+ target_gen_pr_transport_id(pr_reg, nacl->se_tpg->proto_id,
+ nacl->initiatorname, isid);
+
/*
* Return pointer to pr_reg for ALL_TG_PT=0
*/
@@ -802,6 +806,9 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration(
core_scsi3_lunacl_undepend_item(deve_tmp);
goto out;
}
+ target_gen_pr_transport_id(pr_reg_atp,
+ nacl_tmp->se_tpg->proto_id,
+ nacl_tmp->initiatorname, isid);
list_add_tail(&pr_reg_atp->pr_reg_atp_mem_list,
&pr_reg->pr_reg_atp_list);
@@ -3829,13 +3836,12 @@ static sense_reason_t
core_scsi3_pri_read_full_status(struct se_cmd *cmd)
{
struct se_device *dev = cmd->se_dev;
- struct se_portal_group *se_tpg;
struct t10_pr_registration *pr_reg, *pr_reg_tmp;
struct t10_reservation *pr_tmpl = &dev->t10_pr;
unsigned char *buf;
u32 add_desc_len = 0, add_len = 0;
u32 off = 8; /* off into first Full Status descriptor */
- int format_code = 0, pr_res_type = 0, pr_res_scope = 0;
+ int pr_res_type = 0, pr_res_scope = 0;
int exp_desc_len, desc_len;
bool all_reg = false;
@@ -3868,7 +3874,6 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
list_for_each_entry_safe(pr_reg, pr_reg_tmp,
&pr_tmpl->registration_list, pr_reg_list) {
- se_tpg = pr_reg->se_tpg;
add_desc_len = 0;
atomic_inc_mb(&pr_reg->pr_res_holders);
@@ -3877,8 +3882,7 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
* Determine expected length of $FABRIC_MOD specific
* TransportID full status descriptor..
*/
- exp_desc_len = target_get_pr_transport_id_len(pr_reg,
- &format_code);
+ exp_desc_len = target_get_pr_transport_id_len(pr_reg);
if (exp_desc_len < 0 ||
exp_desc_len + add_len > cmd->data_length) {
pr_warn("SPC-3 PRIN READ_FULL_STATUS ran"
@@ -3938,13 +3942,10 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
} else
off += 2; /* Skip over RELATIVE TARGET PORT IDENTIFIER */
- buf[off+4] = se_tpg->proto_id;
-
/*
* Now, have the $FABRIC_MOD fill in the transport ID.
*/
- desc_len = target_get_pr_transport_id(pr_reg,
- &format_code, &buf[off+4]);
+ desc_len = target_get_pr_transport_id(pr_reg, &buf[off+4]);
spin_lock(&pr_tmpl->registration_lock);
atomic_dec_mb(&pr_reg->pr_res_holders);
@@ -347,6 +347,8 @@ struct t10_pr_registration {
/* Used during APTPL metadata reading */
#define PR_APTPL_MAX_IPORT_LEN 256
unsigned char pr_iport[PR_APTPL_MAX_IPORT_LEN];
+#define PR_REG_TID_LEN 228
+ char pr_tid[PR_REG_TID_LEN];
/* Reservation effects all target ports */
int pr_reg_all_tg_pt;
/* Activate Persistence across Target Power Loss */
Store TransportID in pr_reg at its creation. Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com> --- drivers/target/target_core_fabric_lib.c | 130 +++++++++--------------- drivers/target/target_core_internal.h | 9 +- drivers/target/target_core_pr.c | 19 ++-- include/target/target_core_base.h | 2 + 4 files changed, 68 insertions(+), 92 deletions(-)