iscsi-target: Move sendtargets parsing into iscsit_process_text_cmd
This patch moves ISCSI_OP_TEXT PDU buffer sanity checks to iscsit_process_text_cmd() code, so that it can be shared with iser-target code. It adds IFC_SENDTARGETS_ALL + iscsi_cmd->text_in_ptr in order to save text payload for ISCSI_OP_TEXT_RSP, and updates iscsit_release_cmd() to assigned memory. 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:
@@ -1995,8 +1995,32 @@ int
|
|||||||
iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
|
iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
|
||||||
struct iscsi_text *hdr)
|
struct iscsi_text *hdr)
|
||||||
{
|
{
|
||||||
|
unsigned char *text_in = cmd->text_in_ptr, *text_ptr;
|
||||||
int cmdsn_ret;
|
int cmdsn_ret;
|
||||||
|
|
||||||
|
if (!text_in) {
|
||||||
|
pr_err("Unable to locate text_in buffer for sendtargets"
|
||||||
|
" discovery\n");
|
||||||
|
goto reject;
|
||||||
|
}
|
||||||
|
if (strncmp("SendTargets", text_in, 11) != 0) {
|
||||||
|
pr_err("Received Text Data that is not"
|
||||||
|
" SendTargets, cannot continue.\n");
|
||||||
|
goto reject;
|
||||||
|
}
|
||||||
|
text_ptr = strchr(text_in, '=');
|
||||||
|
if (!text_ptr) {
|
||||||
|
pr_err("No \"=\" separator found in Text Data,"
|
||||||
|
" cannot continue.\n");
|
||||||
|
goto reject;
|
||||||
|
}
|
||||||
|
if (!strncmp("=All", text_ptr, 4)) {
|
||||||
|
cmd->cmd_flags |= IFC_SENDTARGETS_ALL;
|
||||||
|
} else {
|
||||||
|
pr_err("Unable to locate valid SendTargets=%s value\n", text_ptr);
|
||||||
|
goto reject;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_bh(&conn->cmd_lock);
|
spin_lock_bh(&conn->cmd_lock);
|
||||||
list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
|
list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
|
||||||
spin_unlock_bh(&conn->cmd_lock);
|
spin_unlock_bh(&conn->cmd_lock);
|
||||||
@@ -2013,6 +2037,10 @@ iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return iscsit_execute_cmd(cmd, 0);
|
return iscsit_execute_cmd(cmd, 0);
|
||||||
|
|
||||||
|
reject:
|
||||||
|
return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR,
|
||||||
|
0, 0, (unsigned char *)hdr, cmd);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iscsit_process_text_cmd);
|
EXPORT_SYMBOL(iscsit_process_text_cmd);
|
||||||
|
|
||||||
@@ -2031,7 +2059,6 @@ iscsit_handle_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
|
|||||||
|
|
||||||
rx_size = payload_length;
|
rx_size = payload_length;
|
||||||
if (payload_length) {
|
if (payload_length) {
|
||||||
char *text_ptr;
|
|
||||||
u32 checksum = 0, data_crc = 0;
|
u32 checksum = 0, data_crc = 0;
|
||||||
u32 padding = 0, pad_bytes = 0;
|
u32 padding = 0, pad_bytes = 0;
|
||||||
int niov = 0, rx_got;
|
int niov = 0, rx_got;
|
||||||
@@ -2043,6 +2070,7 @@ iscsit_handle_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
|
|||||||
" incoming text parameters\n");
|
" incoming text parameters\n");
|
||||||
goto reject;
|
goto reject;
|
||||||
}
|
}
|
||||||
|
cmd->text_in_ptr = text_in;
|
||||||
|
|
||||||
memset(iov, 0, 3 * sizeof(struct kvec));
|
memset(iov, 0, 3 * sizeof(struct kvec));
|
||||||
iov[niov].iov_base = text_in;
|
iov[niov].iov_base = text_in;
|
||||||
@@ -2101,30 +2129,13 @@ iscsit_handle_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
|
|||||||
text_in[payload_length - 1] = '\0';
|
text_in[payload_length - 1] = '\0';
|
||||||
pr_debug("Successfully read %d bytes of text"
|
pr_debug("Successfully read %d bytes of text"
|
||||||
" data.\n", payload_length);
|
" data.\n", payload_length);
|
||||||
|
|
||||||
if (strncmp("SendTargets", text_in, 11) != 0) {
|
|
||||||
pr_err("Received Text Data that is not"
|
|
||||||
" SendTargets, cannot continue.\n");
|
|
||||||
goto reject;
|
|
||||||
}
|
|
||||||
text_ptr = strchr(text_in, '=');
|
|
||||||
if (!text_ptr) {
|
|
||||||
pr_err("No \"=\" separator found in Text Data,"
|
|
||||||
" cannot continue.\n");
|
|
||||||
goto reject;
|
|
||||||
}
|
|
||||||
if (strncmp("=All", text_ptr, 4) != 0) {
|
|
||||||
pr_err("Unable to locate All value for"
|
|
||||||
" SendTargets key, cannot continue.\n");
|
|
||||||
goto reject;
|
|
||||||
}
|
|
||||||
kfree(text_in);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return iscsit_process_text_cmd(conn, cmd, hdr);
|
return iscsit_process_text_cmd(conn, cmd, hdr);
|
||||||
|
|
||||||
reject:
|
reject:
|
||||||
kfree(text_in);
|
kfree(cmd->text_in_ptr);
|
||||||
|
cmd->text_in_ptr = NULL;
|
||||||
return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR,
|
return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR,
|
||||||
0, 0, buf, cmd);
|
0, 0, buf, cmd);
|
||||||
}
|
}
|
||||||
|
@@ -133,6 +133,7 @@ enum cmd_flags_table {
|
|||||||
ICF_ATTACHED_TO_RQUEUE = 0x00000040,
|
ICF_ATTACHED_TO_RQUEUE = 0x00000040,
|
||||||
ICF_OOO_CMDSN = 0x00000080,
|
ICF_OOO_CMDSN = 0x00000080,
|
||||||
ICF_REJECT_FAIL_CONN = 0x00000100,
|
ICF_REJECT_FAIL_CONN = 0x00000100,
|
||||||
|
IFC_SENDTARGETS_ALL = 0x00000200,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* struct iscsi_cmd->i_state */
|
/* struct iscsi_cmd->i_state */
|
||||||
@@ -427,6 +428,8 @@ struct iscsi_cmd {
|
|||||||
u32 tx_size;
|
u32 tx_size;
|
||||||
/* Buffer used for various purposes */
|
/* Buffer used for various purposes */
|
||||||
void *buf_ptr;
|
void *buf_ptr;
|
||||||
|
/* Used by SendTargets=[iqn.,eui.] discovery */
|
||||||
|
void *text_in_ptr;
|
||||||
/* See include/linux/dma-mapping.h */
|
/* See include/linux/dma-mapping.h */
|
||||||
enum dma_data_direction data_direction;
|
enum dma_data_direction data_direction;
|
||||||
/* iSCSI PDU Header + CRC */
|
/* iSCSI PDU Header + CRC */
|
||||||
|
@@ -681,6 +681,7 @@ void iscsit_release_cmd(struct iscsi_cmd *cmd)
|
|||||||
kfree(cmd->seq_list);
|
kfree(cmd->seq_list);
|
||||||
kfree(cmd->tmr_req);
|
kfree(cmd->tmr_req);
|
||||||
kfree(cmd->iov_data);
|
kfree(cmd->iov_data);
|
||||||
|
kfree(cmd->text_in_ptr);
|
||||||
|
|
||||||
kmem_cache_free(lio_cmd_cache, cmd);
|
kmem_cache_free(lio_cmd_cache, cmd);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user