iscsi-target: Add IFC_SENDTARGETS_SINGLE support
This patch changes ISCSI_OP_TEXT handling of SendTargets=[iqn.,eui.] payloads to return explicit discovery information. It adds checks to iscsit_process_text_cmd() and adds the special single $TARGETNAME discovery case in iscsit_build_sendtargets_response() code. Cc: Or Gerlitz <ogerlitz@mellanox.com> Cc: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
9864ca9d27
commit
6665889c84
|
@ -2016,6 +2016,9 @@ iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
|
||||||
}
|
}
|
||||||
if (!strncmp("=All", text_ptr, 4)) {
|
if (!strncmp("=All", text_ptr, 4)) {
|
||||||
cmd->cmd_flags |= IFC_SENDTARGETS_ALL;
|
cmd->cmd_flags |= IFC_SENDTARGETS_ALL;
|
||||||
|
} else if (!strncmp("=iqn.", text_ptr, 5) ||
|
||||||
|
!strncmp("=eui.", text_ptr, 5)) {
|
||||||
|
cmd->cmd_flags |= IFC_SENDTARGETS_SINGLE;
|
||||||
} else {
|
} else {
|
||||||
pr_err("Unable to locate valid SendTargets=%s value\n", text_ptr);
|
pr_err("Unable to locate valid SendTargets=%s value\n", text_ptr);
|
||||||
goto reject;
|
goto reject;
|
||||||
|
@ -3398,6 +3401,7 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd)
|
||||||
struct iscsi_tpg_np *tpg_np;
|
struct iscsi_tpg_np *tpg_np;
|
||||||
int buffer_len, end_of_buf = 0, len = 0, payload_len = 0;
|
int buffer_len, end_of_buf = 0, len = 0, payload_len = 0;
|
||||||
unsigned char buf[ISCSI_IQN_LEN+12]; /* iqn + "TargetName=" + \0 */
|
unsigned char buf[ISCSI_IQN_LEN+12]; /* iqn + "TargetName=" + \0 */
|
||||||
|
unsigned char *text_in = cmd->text_in_ptr, *text_ptr = NULL;
|
||||||
|
|
||||||
buffer_len = max(conn->conn_ops->MaxRecvDataSegmentLength,
|
buffer_len = max(conn->conn_ops->MaxRecvDataSegmentLength,
|
||||||
SENDTARGETS_BUF_LIMIT);
|
SENDTARGETS_BUF_LIMIT);
|
||||||
|
@ -3408,9 +3412,30 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd)
|
||||||
" response.\n");
|
" response.\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Locate pointer to iqn./eui. string for IFC_SENDTARGETS_SINGLE
|
||||||
|
* explicit case..
|
||||||
|
*/
|
||||||
|
if (cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) {
|
||||||
|
text_ptr = strchr(text_in, '=');
|
||||||
|
if (!text_ptr) {
|
||||||
|
pr_err("Unable to locate '=' string in text_in:"
|
||||||
|
" %s\n", text_in);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Skip over '=' character..
|
||||||
|
*/
|
||||||
|
text_ptr += 1;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock(&tiqn_lock);
|
spin_lock(&tiqn_lock);
|
||||||
list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) {
|
list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) {
|
||||||
|
if ((cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) &&
|
||||||
|
strcmp(tiqn->tiqn, text_ptr)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
len = sprintf(buf, "TargetName=%s", tiqn->tiqn);
|
len = sprintf(buf, "TargetName=%s", tiqn->tiqn);
|
||||||
len += 1;
|
len += 1;
|
||||||
|
|
||||||
|
@ -3464,6 +3489,9 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd)
|
||||||
eob:
|
eob:
|
||||||
if (end_of_buf)
|
if (end_of_buf)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (cmd->cmd_flags & IFC_SENDTARGETS_SINGLE)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
spin_unlock(&tiqn_lock);
|
spin_unlock(&tiqn_lock);
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,7 @@ enum cmd_flags_table {
|
||||||
ICF_OOO_CMDSN = 0x00000080,
|
ICF_OOO_CMDSN = 0x00000080,
|
||||||
ICF_REJECT_FAIL_CONN = 0x00000100,
|
ICF_REJECT_FAIL_CONN = 0x00000100,
|
||||||
IFC_SENDTARGETS_ALL = 0x00000200,
|
IFC_SENDTARGETS_ALL = 0x00000200,
|
||||||
|
IFC_SENDTARGETS_SINGLE = 0x00000400,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* struct iscsi_cmd->i_state */
|
/* struct iscsi_cmd->i_state */
|
||||||
|
|
Loading…
Reference in a new issue