Commit 1aa58ccd authored by Nicholas Bellinger's avatar Nicholas Bellinger Committed by Greg Kroah-Hartman

iscsi-target: Fix iscsit_add_reject* usage for iser

commit ba159914 upstream

This patch changes iscsit_add_reject() + iscsit_add_reject_from_cmd()
usage to not sleep on iscsi_cmd->reject_comp to address a free-after-use
usage bug in v3.10 with iser-target code.

It saves ->reject_reason for use within iscsit_build_reject() so the
correct value for both transport cases.  It also drops the legacy
fail_conn parameter usage throughput iscsi-target code and adds
two iscsit_add_reject_cmd() and iscsit_reject_cmd helper functions,
along with various small cleanups.

(v2: Re-enable target_put_sess_cmd() to be called from
     iscsit_add_reject_from_cmd() for rejects invoked after
     target_get_sess_cmd() has been called)
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
Cc: Or Gerlitz <ogerlitz@mellanox.com>
Cc: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6655d76e
...@@ -957,11 +957,6 @@ isert_handle_scsi_cmd(struct isert_conn *isert_conn, ...@@ -957,11 +957,6 @@ isert_handle_scsi_cmd(struct isert_conn *isert_conn,
if (!rc && dump_payload == false && unsol_data) if (!rc && dump_payload == false && unsol_data)
iscsit_set_unsoliticed_dataout(cmd); iscsit_set_unsoliticed_dataout(cmd);
if (rc == CMDSN_ERROR_CANNOT_RECOVER)
return iscsit_add_reject_from_cmd(
ISCSI_REASON_PROTOCOL_ERROR,
1, 0, (unsigned char *)hdr, cmd);
return 0; return 0;
} }
......
...@@ -628,25 +628,18 @@ static void __exit iscsi_target_cleanup_module(void) ...@@ -628,25 +628,18 @@ static void __exit iscsi_target_cleanup_module(void)
} }
static int iscsit_add_reject( static int iscsit_add_reject(
struct iscsi_conn *conn,
u8 reason, u8 reason,
int fail_conn, unsigned char *buf)
unsigned char *buf,
struct iscsi_conn *conn)
{ {
struct iscsi_cmd *cmd; struct iscsi_cmd *cmd;
struct iscsi_reject *hdr;
int ret;
cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
if (!cmd) if (!cmd)
return -1; return -1;
cmd->iscsi_opcode = ISCSI_OP_REJECT; cmd->iscsi_opcode = ISCSI_OP_REJECT;
if (fail_conn) cmd->reject_reason = reason;
cmd->cmd_flags |= ICF_REJECT_FAIL_CONN;
hdr = (struct iscsi_reject *) cmd->pdu;
hdr->reason = reason;
cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL);
if (!cmd->buf_ptr) { if (!cmd->buf_ptr) {
...@@ -662,23 +655,16 @@ static int iscsit_add_reject( ...@@ -662,23 +655,16 @@ static int iscsit_add_reject(
cmd->i_state = ISTATE_SEND_REJECT; cmd->i_state = ISTATE_SEND_REJECT;
iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
ret = wait_for_completion_interruptible(&cmd->reject_comp);
if (ret != 0)
return -1; return -1;
return (!fail_conn) ? 0 : -1;
} }
int iscsit_add_reject_from_cmd( static int iscsit_add_reject_from_cmd(
struct iscsi_cmd *cmd,
u8 reason, u8 reason,
int fail_conn, bool add_to_conn,
int add_to_conn, unsigned char *buf)
unsigned char *buf,
struct iscsi_cmd *cmd)
{ {
struct iscsi_conn *conn; struct iscsi_conn *conn;
struct iscsi_reject *hdr;
int ret;
if (!cmd->conn) { if (!cmd->conn) {
pr_err("cmd->conn is NULL for ITT: 0x%08x\n", pr_err("cmd->conn is NULL for ITT: 0x%08x\n",
...@@ -688,11 +674,7 @@ int iscsit_add_reject_from_cmd( ...@@ -688,11 +674,7 @@ int iscsit_add_reject_from_cmd(
conn = cmd->conn; conn = cmd->conn;
cmd->iscsi_opcode = ISCSI_OP_REJECT; cmd->iscsi_opcode = ISCSI_OP_REJECT;
if (fail_conn) cmd->reject_reason = reason;
cmd->cmd_flags |= ICF_REJECT_FAIL_CONN;
hdr = (struct iscsi_reject *) cmd->pdu;
hdr->reason = reason;
cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL);
if (!cmd->buf_ptr) { if (!cmd->buf_ptr) {
...@@ -709,8 +691,6 @@ int iscsit_add_reject_from_cmd( ...@@ -709,8 +691,6 @@ int iscsit_add_reject_from_cmd(
cmd->i_state = ISTATE_SEND_REJECT; cmd->i_state = ISTATE_SEND_REJECT;
iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
ret = wait_for_completion_interruptible(&cmd->reject_comp);
/* /*
* Perform the kref_put now if se_cmd has already been setup by * Perform the kref_put now if se_cmd has already been setup by
* scsit_setup_scsi_cmd() * scsit_setup_scsi_cmd()
...@@ -719,12 +699,19 @@ int iscsit_add_reject_from_cmd( ...@@ -719,12 +699,19 @@ int iscsit_add_reject_from_cmd(
pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n"); pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n");
target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
} }
if (ret != 0)
return -1; return -1;
}
static int iscsit_add_reject_cmd(struct iscsi_cmd *cmd, u8 reason,
unsigned char *buf)
{
return iscsit_add_reject_from_cmd(cmd, reason, true, buf);
}
return (!fail_conn) ? 0 : -1; int iscsit_reject_cmd(struct iscsi_cmd *cmd, u8 reason, unsigned char *buf)
{
return iscsit_add_reject_from_cmd(cmd, reason, false, buf);
} }
EXPORT_SYMBOL(iscsit_add_reject_from_cmd);
/* /*
* Map some portion of the allocated scatterlist to an iovec, suitable for * Map some portion of the allocated scatterlist to an iovec, suitable for
...@@ -844,8 +831,8 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ...@@ -844,8 +831,8 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
!(hdr->flags & ISCSI_FLAG_CMD_FINAL)) { !(hdr->flags & ISCSI_FLAG_CMD_FINAL)) {
pr_err("ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL" pr_err("ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL"
" not set. Bad iSCSI Initiator.\n"); " not set. Bad iSCSI Initiator.\n");
return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, return iscsit_add_reject_cmd(cmd,
1, 1, buf, cmd); ISCSI_REASON_BOOKMARK_INVALID, buf);
} }
if (((hdr->flags & ISCSI_FLAG_CMD_READ) || if (((hdr->flags & ISCSI_FLAG_CMD_READ) ||
...@@ -865,8 +852,8 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ...@@ -865,8 +852,8 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
pr_err("ISCSI_FLAG_CMD_READ or ISCSI_FLAG_CMD_WRITE" pr_err("ISCSI_FLAG_CMD_READ or ISCSI_FLAG_CMD_WRITE"
" set when Expected Data Transfer Length is 0 for" " set when Expected Data Transfer Length is 0 for"
" CDB: 0x%02x. Bad iSCSI Initiator.\n", hdr->cdb[0]); " CDB: 0x%02x. Bad iSCSI Initiator.\n", hdr->cdb[0]);
return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, return iscsit_add_reject_cmd(cmd,
1, 1, buf, cmd); ISCSI_REASON_BOOKMARK_INVALID, buf);
} }
done: done:
...@@ -875,62 +862,62 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ...@@ -875,62 +862,62 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
pr_err("ISCSI_FLAG_CMD_READ and/or ISCSI_FLAG_CMD_WRITE" pr_err("ISCSI_FLAG_CMD_READ and/or ISCSI_FLAG_CMD_WRITE"
" MUST be set if Expected Data Transfer Length is not 0." " MUST be set if Expected Data Transfer Length is not 0."
" Bad iSCSI Initiator\n"); " Bad iSCSI Initiator\n");
return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, return iscsit_add_reject_cmd(cmd,
1, 1, buf, cmd); ISCSI_REASON_BOOKMARK_INVALID, buf);
} }
if ((hdr->flags & ISCSI_FLAG_CMD_READ) && if ((hdr->flags & ISCSI_FLAG_CMD_READ) &&
(hdr->flags & ISCSI_FLAG_CMD_WRITE)) { (hdr->flags & ISCSI_FLAG_CMD_WRITE)) {
pr_err("Bidirectional operations not supported!\n"); pr_err("Bidirectional operations not supported!\n");
return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, return iscsit_add_reject_cmd(cmd,
1, 1, buf, cmd); ISCSI_REASON_BOOKMARK_INVALID, buf);
} }
if (hdr->opcode & ISCSI_OP_IMMEDIATE) { if (hdr->opcode & ISCSI_OP_IMMEDIATE) {
pr_err("Illegally set Immediate Bit in iSCSI Initiator" pr_err("Illegally set Immediate Bit in iSCSI Initiator"
" Scsi Command PDU.\n"); " Scsi Command PDU.\n");
return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, return iscsit_add_reject_cmd(cmd,
1, 1, buf, cmd); ISCSI_REASON_BOOKMARK_INVALID, buf);
} }
if (payload_length && !conn->sess->sess_ops->ImmediateData) { if (payload_length && !conn->sess->sess_ops->ImmediateData) {
pr_err("ImmediateData=No but DataSegmentLength=%u," pr_err("ImmediateData=No but DataSegmentLength=%u,"
" protocol error.\n", payload_length); " protocol error.\n", payload_length);
return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, return iscsit_add_reject_cmd(cmd,
1, 1, buf, cmd); ISCSI_REASON_PROTOCOL_ERROR, buf);
} }
if ((be32_to_cpu(hdr->data_length )== payload_length) && if ((be32_to_cpu(hdr->data_length) == payload_length) &&
(!(hdr->flags & ISCSI_FLAG_CMD_FINAL))) { (!(hdr->flags & ISCSI_FLAG_CMD_FINAL))) {
pr_err("Expected Data Transfer Length and Length of" pr_err("Expected Data Transfer Length and Length of"
" Immediate Data are the same, but ISCSI_FLAG_CMD_FINAL" " Immediate Data are the same, but ISCSI_FLAG_CMD_FINAL"
" bit is not set protocol error\n"); " bit is not set protocol error\n");
return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, return iscsit_add_reject_cmd(cmd,
1, 1, buf, cmd); ISCSI_REASON_PROTOCOL_ERROR, buf);
} }
if (payload_length > be32_to_cpu(hdr->data_length)) { if (payload_length > be32_to_cpu(hdr->data_length)) {
pr_err("DataSegmentLength: %u is greater than" pr_err("DataSegmentLength: %u is greater than"
" EDTL: %u, protocol error.\n", payload_length, " EDTL: %u, protocol error.\n", payload_length,
hdr->data_length); hdr->data_length);
return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, return iscsit_add_reject_cmd(cmd,
1, 1, buf, cmd); ISCSI_REASON_PROTOCOL_ERROR, buf);
} }
if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
pr_err("DataSegmentLength: %u is greater than" pr_err("DataSegmentLength: %u is greater than"
" MaxXmitDataSegmentLength: %u, protocol error.\n", " MaxXmitDataSegmentLength: %u, protocol error.\n",
payload_length, conn->conn_ops->MaxXmitDataSegmentLength); payload_length, conn->conn_ops->MaxXmitDataSegmentLength);
return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, return iscsit_add_reject_cmd(cmd,
1, 1, buf, cmd); ISCSI_REASON_PROTOCOL_ERROR, buf);
} }
if (payload_length > conn->sess->sess_ops->FirstBurstLength) { if (payload_length > conn->sess->sess_ops->FirstBurstLength) {
pr_err("DataSegmentLength: %u is greater than" pr_err("DataSegmentLength: %u is greater than"
" FirstBurstLength: %u, protocol error.\n", " FirstBurstLength: %u, protocol error.\n",
payload_length, conn->sess->sess_ops->FirstBurstLength); payload_length, conn->sess->sess_ops->FirstBurstLength);
return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, return iscsit_add_reject_cmd(cmd,
1, 1, buf, cmd); ISCSI_REASON_BOOKMARK_INVALID, buf);
} }
data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE : data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE :
...@@ -985,9 +972,8 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ...@@ -985,9 +972,8 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
dr = iscsit_allocate_datain_req(); dr = iscsit_allocate_datain_req();
if (!dr) if (!dr)
return iscsit_add_reject_from_cmd( return iscsit_add_reject_cmd(cmd,
ISCSI_REASON_BOOKMARK_NO_RESOURCES, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
1, 1, buf, cmd);
iscsit_attach_datain_req(cmd, dr); iscsit_attach_datain_req(cmd, dr);
} }
...@@ -1015,18 +1001,16 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ...@@ -1015,18 +1001,16 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
cmd->sense_reason = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb); cmd->sense_reason = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb);
if (cmd->sense_reason) { if (cmd->sense_reason) {
if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) { if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) {
return iscsit_add_reject_from_cmd( return iscsit_add_reject_cmd(cmd,
ISCSI_REASON_BOOKMARK_NO_RESOURCES, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
1, 1, buf, cmd);
} }
goto attach_cmd; goto attach_cmd;
} }
if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) { if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) {
return iscsit_add_reject_from_cmd( return iscsit_add_reject_cmd(cmd,
ISCSI_REASON_BOOKMARK_NO_RESOURCES, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
1, 1, buf, cmd);
} }
attach_cmd: attach_cmd:
...@@ -1075,10 +1059,6 @@ int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ...@@ -1075,10 +1059,6 @@ int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
return 0; return 0;
} else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) {
return iscsit_add_reject_from_cmd(
ISCSI_REASON_PROTOCOL_ERROR,
1, 0, (unsigned char *)hdr, cmd);
} }
} }
...@@ -1149,11 +1129,6 @@ iscsit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr, ...@@ -1149,11 +1129,6 @@ iscsit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr,
} else if (cmd->unsolicited_data) } else if (cmd->unsolicited_data)
iscsit_set_unsoliticed_dataout(cmd); iscsit_set_unsoliticed_dataout(cmd);
if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
return iscsit_add_reject_from_cmd(
ISCSI_REASON_PROTOCOL_ERROR,
1, 0, (unsigned char *)hdr, cmd);
} else if (immed_ret == IMMEDIATE_DATA_ERL1_CRC_FAILURE) { } else if (immed_ret == IMMEDIATE_DATA_ERL1_CRC_FAILURE) {
/* /*
* Immediate Data failed DataCRC and ERL>=1, * Immediate Data failed DataCRC and ERL>=1,
...@@ -1190,9 +1165,8 @@ iscsit_handle_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ...@@ -1190,9 +1165,8 @@ iscsit_handle_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
* traditional iSCSI block I/O. * traditional iSCSI block I/O.
*/ */
if (iscsit_allocate_iovecs(cmd) < 0) { if (iscsit_allocate_iovecs(cmd) < 0) {
return iscsit_add_reject_from_cmd( return iscsit_add_reject_cmd(cmd,
ISCSI_REASON_BOOKMARK_NO_RESOURCES, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
1, 0, buf, cmd);
} }
immed_data = cmd->immediate_data; immed_data = cmd->immediate_data;
...@@ -1283,8 +1257,8 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf, ...@@ -1283,8 +1257,8 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf,
if (!payload_length) { if (!payload_length) {
pr_err("DataOUT payload is ZERO, protocol error.\n"); pr_err("DataOUT payload is ZERO, protocol error.\n");
return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
buf, conn); buf);
} }
/* iSCSI write */ /* iSCSI write */
...@@ -1301,8 +1275,8 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf, ...@@ -1301,8 +1275,8 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf,
pr_err("DataSegmentLength: %u is greater than" pr_err("DataSegmentLength: %u is greater than"
" MaxXmitDataSegmentLength: %u\n", payload_length, " MaxXmitDataSegmentLength: %u\n", payload_length,
conn->conn_ops->MaxXmitDataSegmentLength); conn->conn_ops->MaxXmitDataSegmentLength);
return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
buf, conn); buf);
} }
cmd = iscsit_find_cmd_from_itt_or_dump(conn, hdr->itt, cmd = iscsit_find_cmd_from_itt_or_dump(conn, hdr->itt,
...@@ -1325,8 +1299,7 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf, ...@@ -1325,8 +1299,7 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf,
if (cmd->data_direction != DMA_TO_DEVICE) { if (cmd->data_direction != DMA_TO_DEVICE) {
pr_err("Command ITT: 0x%08x received DataOUT for a" pr_err("Command ITT: 0x%08x received DataOUT for a"
" NON-WRITE command.\n", cmd->init_task_tag); " NON-WRITE command.\n", cmd->init_task_tag);
return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf);
1, 0, buf, cmd);
} }
se_cmd = &cmd->se_cmd; se_cmd = &cmd->se_cmd;
iscsit_mod_dataout_timer(cmd); iscsit_mod_dataout_timer(cmd);
...@@ -1335,8 +1308,7 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf, ...@@ -1335,8 +1308,7 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf,
pr_err("DataOut Offset: %u, Length %u greater than" pr_err("DataOut Offset: %u, Length %u greater than"
" iSCSI Command EDTL %u, protocol error.\n", " iSCSI Command EDTL %u, protocol error.\n",
hdr->offset, payload_length, cmd->se_cmd.data_length); hdr->offset, payload_length, cmd->se_cmd.data_length);
return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_INVALID, buf);
1, 0, buf, cmd);
} }
if (cmd->unsolicited_data) { if (cmd->unsolicited_data) {
...@@ -1557,8 +1529,8 @@ int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ...@@ -1557,8 +1529,8 @@ int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
if (hdr->itt == RESERVED_ITT && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) { if (hdr->itt == RESERVED_ITT && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
pr_err("NOPOUT ITT is reserved, but Immediate Bit is" pr_err("NOPOUT ITT is reserved, but Immediate Bit is"
" not set, protocol error.\n"); " not set, protocol error.\n");
return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR,
buf, conn); (unsigned char *)hdr);
} }
if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
...@@ -1566,8 +1538,8 @@ int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ...@@ -1566,8 +1538,8 @@ int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
" greater than MaxXmitDataSegmentLength: %u, protocol" " greater than MaxXmitDataSegmentLength: %u, protocol"
" error.\n", payload_length, " error.\n", payload_length,
conn->conn_ops->MaxXmitDataSegmentLength); conn->conn_ops->MaxXmitDataSegmentLength);
return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR,
buf, conn); (unsigned char *)hdr);
} }
pr_debug("Got NOPOUT Ping %s ITT: 0x%08x, TTT: 0x%08x," pr_debug("Got NOPOUT Ping %s ITT: 0x%08x, TTT: 0x%08x,"
...@@ -1584,9 +1556,9 @@ int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ...@@ -1584,9 +1556,9 @@ int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
*/ */
if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) {
if (!cmd) if (!cmd)
return iscsit_add_reject( return iscsit_reject_cmd(cmd,
ISCSI_REASON_BOOKMARK_NO_RESOURCES, ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1, buf, conn); (unsigned char *)hdr);
cmd->iscsi_opcode = ISCSI_OP_NOOP_OUT; cmd->iscsi_opcode = ISCSI_OP_NOOP_OUT;
cmd->i_state = ISTATE_SEND_NOPIN; cmd->i_state = ISTATE_SEND_NOPIN;
...@@ -1706,9 +1678,7 @@ int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ...@@ -1706,9 +1678,7 @@ int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
goto ping_out; goto ping_out;
} }
if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
return iscsit_add_reject_from_cmd( return -1;
ISCSI_REASON_PROTOCOL_ERROR,
1, 0, buf, cmd);
return 0; return 0;
} }
...@@ -1782,8 +1752,8 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ...@@ -1782,8 +1752,8 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
pr_err("Task Management Request TASK_REASSIGN not" pr_err("Task Management Request TASK_REASSIGN not"
" issued as immediate command, bad iSCSI Initiator" " issued as immediate command, bad iSCSI Initiator"
"implementation\n"); "implementation\n");
return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, return iscsit_add_reject_cmd(cmd,
1, 1, buf, cmd); ISCSI_REASON_PROTOCOL_ERROR, buf);
} }
if ((function != ISCSI_TM_FUNC_ABORT_TASK) && if ((function != ISCSI_TM_FUNC_ABORT_TASK) &&
be32_to_cpu(hdr->refcmdsn) != ISCSI_RESERVED_TAG) be32_to_cpu(hdr->refcmdsn) != ISCSI_RESERVED_TAG)
...@@ -1795,9 +1765,9 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ...@@ -1795,9 +1765,9 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
if (!cmd->tmr_req) { if (!cmd->tmr_req) {
pr_err("Unable to allocate memory for" pr_err("Unable to allocate memory for"
" Task Management command!\n"); " Task Management command!\n");
return iscsit_add_reject_from_cmd( return iscsit_add_reject_cmd(cmd,
ISCSI_REASON_BOOKMARK_NO_RESOURCES, ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1, 1, buf, cmd); buf);
} }
/* /*
...@@ -1842,17 +1812,15 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ...@@ -1842,17 +1812,15 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
default: default:
pr_err("Unknown iSCSI TMR Function:" pr_err("Unknown iSCSI TMR Function:"
" 0x%02x\n", function); " 0x%02x\n", function);
return iscsit_add_reject_from_cmd( return iscsit_add_reject_cmd(cmd,
ISCSI_REASON_BOOKMARK_NO_RESOURCES, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
1, 1, buf, cmd);
} }
ret = core_tmr_alloc_req(&cmd->se_cmd, cmd->tmr_req, ret = core_tmr_alloc_req(&cmd->se_cmd, cmd->tmr_req,
tcm_function, GFP_KERNEL); tcm_function, GFP_KERNEL);
if (ret < 0) if (ret < 0)
return iscsit_add_reject_from_cmd( return iscsit_add_reject_cmd(cmd,
ISCSI_REASON_BOOKMARK_NO_RESOURCES, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
1, 1, buf, cmd);
cmd->tmr_req->se_tmr_req = cmd->se_cmd.se_tmr_req; cmd->tmr_req->se_tmr_req = cmd->se_cmd.se_tmr_req;
} }
...@@ -1911,9 +1879,8 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ...@@ -1911,9 +1879,8 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
break; break;
if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0) if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0)
return iscsit_add_reject_from_cmd( return iscsit_add_reject_cmd(cmd,
ISCSI_REASON_BOOKMARK_INVALID, 1, 1, ISCSI_REASON_BOOKMARK_INVALID, buf);
buf, cmd);
break; break;
default: default:
pr_err("Unknown TMR function: 0x%02x, protocol" pr_err("Unknown TMR function: 0x%02x, protocol"
...@@ -1937,9 +1904,7 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ...@@ -1937,9 +1904,7 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP)
return 0; return 0;
else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
return iscsit_add_reject_from_cmd( return -1;
ISCSI_REASON_PROTOCOL_ERROR,
1, 0, buf, cmd);
} }
iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
...@@ -1989,8 +1954,7 @@ static int iscsit_handle_text_cmd( ...@@ -1989,8 +1954,7 @@ static int iscsit_handle_text_cmd(
pr_err("Unable to accept text parameter length: %u" pr_err("Unable to accept text parameter length: %u"
"greater than MaxXmitDataSegmentLength %u.\n", "greater than MaxXmitDataSegmentLength %u.\n",
payload_length, conn->conn_ops->MaxXmitDataSegmentLength); payload_length, conn->conn_ops->MaxXmitDataSegmentLength);
return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, buf);
buf, conn);
} }
pr_debug("Got Text Request: ITT: 0x%08x, CmdSN: 0x%08x," pr_debug("Got Text Request: ITT: 0x%08x, CmdSN: 0x%08x,"
...@@ -2092,8 +2056,8 @@ static int iscsit_handle_text_cmd( ...@@ -2092,8 +2056,8 @@ static int iscsit_handle_text_cmd(
cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
if (!cmd) if (!cmd)
return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, return iscsit_add_reject(conn,
1, buf, conn); ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
cmd->iscsi_opcode = ISCSI_OP_TEXT; cmd->iscsi_opcode = ISCSI_OP_TEXT;
cmd->i_state = ISTATE_SEND_TEXTRSP; cmd->i_state = ISTATE_SEND_TEXTRSP;
...@@ -2113,9 +2077,7 @@ static int iscsit_handle_text_cmd( ...@@ -2113,9 +2077,7 @@ static int iscsit_handle_text_cmd(
if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) { if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
return iscsit_add_reject_from_cmd( return -1;
ISCSI_REASON_PROTOCOL_ERROR,
1, 0, buf, cmd);
return 0; return 0;
} }
...@@ -2301,13 +2263,10 @@ iscsit_handle_logout_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ...@@ -2301,13 +2263,10 @@ iscsit_handle_logout_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
return ret; return ret;
} else { } else {
cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) { if (cmdsn_ret == CMDSN_LOWER_THAN_EXP)
logout_remove = 0; logout_remove = 0;
} else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) { else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
return iscsit_add_reject_from_cmd( return -1;
ISCSI_REASON_PROTOCOL_ERROR,
1, 0, buf, cmd);
}
} }
return logout_remove; return logout_remove;
...@@ -2331,8 +2290,8 @@ static int iscsit_handle_snack( ...@@ -2331,8 +2290,8 @@ static int iscsit_handle_snack(
if (!conn->sess->sess_ops->ErrorRecoveryLevel) { if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
pr_err("Initiator sent SNACK request while in" pr_err("Initiator sent SNACK request while in"
" ErrorRecoveryLevel=0.\n"); " ErrorRecoveryLevel=0.\n");
return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
buf, conn); buf);
} }
/* /*
* SNACK_DATA and SNACK_R2T are both 0, so check which function to * SNACK_DATA and SNACK_R2T are both 0, so check which function to
...@@ -2356,13 +2315,13 @@ static int iscsit_handle_snack( ...@@ -2356,13 +2315,13 @@ static int iscsit_handle_snack(
case ISCSI_FLAG_SNACK_TYPE_RDATA: case ISCSI_FLAG_SNACK_TYPE_RDATA:
/* FIXME: Support R-Data SNACK */ /* FIXME: Support R-Data SNACK */
pr_err("R-Data SNACK Not Supported.\n"); pr_err("R-Data SNACK Not Supported.\n");
return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
buf, conn); buf);
default: default:
pr_err("Unknown SNACK type 0x%02x, protocol" pr_err("Unknown SNACK type 0x%02x, protocol"
" error.\n", hdr->flags & 0x0f); " error.\n", hdr->flags & 0x0f);
return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
buf, conn); buf);
} }
return 0; return 0;
...@@ -2434,14 +2393,14 @@ static int iscsit_handle_immediate_data( ...@@ -2434,14 +2393,14 @@ static int iscsit_handle_immediate_data(
pr_err("Unable to recover from" pr_err("Unable to recover from"
" Immediate Data digest failure while" " Immediate Data digest failure while"
" in ERL=0.\n"); " in ERL=0.\n");
iscsit_add_reject_from_cmd( iscsit_reject_cmd(cmd,
ISCSI_REASON_DATA_DIGEST_ERROR, ISCSI_REASON_DATA_DIGEST_ERROR,
1, 0, (unsigned char *)hdr, cmd); (unsigned char *)hdr);
return IMMEDIATE_DATA_CANNOT_RECOVER; return IMMEDIATE_DATA_CANNOT_RECOVER;
} else { } else {
iscsit_add_reject_from_cmd( iscsit_reject_cmd(cmd,
ISCSI_REASON_DATA_DIGEST_ERROR, ISCSI_REASON_DATA_DIGEST_ERROR,
0, 0, (unsigned char *)hdr, cmd); (unsigned char *)hdr);
return IMMEDIATE_DATA_ERL1_CRC_FAILURE; return IMMEDIATE_DATA_ERL1_CRC_FAILURE;
} }
} else { } else {
...@@ -3541,6 +3500,7 @@ iscsit_build_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn, ...@@ -3541,6 +3500,7 @@ iscsit_build_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
struct iscsi_reject *hdr) struct iscsi_reject *hdr)
{ {
hdr->opcode = ISCSI_OP_REJECT; hdr->opcode = ISCSI_OP_REJECT;
hdr->reason = cmd->reject_reason;
hdr->flags |= ISCSI_FLAG_CMD_FINAL; hdr->flags |= ISCSI_FLAG_CMD_FINAL;
hton24(hdr->dlength, ISCSI_HDR_LEN); hton24(hdr->dlength, ISCSI_HDR_LEN);
hdr->ffffffff = cpu_to_be32(0xffffffff); hdr->ffffffff = cpu_to_be32(0xffffffff);
...@@ -3814,18 +3774,11 @@ iscsit_response_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) ...@@ -3814,18 +3774,11 @@ iscsit_response_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state)
case ISTATE_SEND_STATUS_RECOVERY: case ISTATE_SEND_STATUS_RECOVERY:
case ISTATE_SEND_TEXTRSP: case ISTATE_SEND_TEXTRSP:
case ISTATE_SEND_TASKMGTRSP: case ISTATE_SEND_TASKMGTRSP:
case ISTATE_SEND_REJECT:
spin_lock_bh(&cmd->istate_lock); spin_lock_bh(&cmd->istate_lock);
cmd->i_state = ISTATE_SENT_STATUS; cmd->i_state = ISTATE_SENT_STATUS;
spin_unlock_bh(&cmd->istate_lock); spin_unlock_bh(&cmd->istate_lock);
break; break;
case ISTATE_SEND_REJECT:
if (cmd->cmd_flags & ICF_REJECT_FAIL_CONN) {
cmd->cmd_flags &= ~ICF_REJECT_FAIL_CONN;
complete(&cmd->reject_comp);
goto err;
}
complete(&cmd->reject_comp);
break;
default: default:
pr_err("Unknown Opcode: 0x%02x ITT:" pr_err("Unknown Opcode: 0x%02x ITT:"
" 0x%08x, i_state: %d on CID: %hu\n", " 0x%08x, i_state: %d on CID: %hu\n",
...@@ -3930,8 +3883,7 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf) ...@@ -3930,8 +3883,7 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf)
case ISCSI_OP_SCSI_CMD: case ISCSI_OP_SCSI_CMD:
cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
if (!cmd) if (!cmd)
return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, goto reject;
1, buf, conn);
ret = iscsit_handle_scsi_cmd(conn, cmd, buf); ret = iscsit_handle_scsi_cmd(conn, cmd, buf);
break; break;
...@@ -3943,16 +3895,14 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf) ...@@ -3943,16 +3895,14 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf)
if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) {
cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
if (!cmd) if (!cmd)
return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, goto reject;
1, buf, conn);
} }
ret = iscsit_handle_nop_out(conn, cmd, buf); ret = iscsit_handle_nop_out(conn, cmd, buf);
break; break;
case ISCSI_OP_SCSI_TMFUNC: case ISCSI_OP_SCSI_TMFUNC:
cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
if (!cmd) if (!cmd)
return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, goto reject;
1, buf, conn);
ret = iscsit_handle_task_mgt_cmd(conn, cmd, buf); ret = iscsit_handle_task_mgt_cmd(conn, cmd, buf);
break; break;
...@@ -3962,8 +3912,7 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf) ...@@ -3962,8 +3912,7 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf)
case ISCSI_OP_LOGOUT: case ISCSI_OP_LOGOUT:
cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
if (!cmd) if (!cmd)
return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, goto reject;
1, buf, conn);
ret = iscsit_handle_logout_cmd(conn, cmd, buf); ret = iscsit_handle_logout_cmd(conn, cmd, buf);
if (ret > 0) if (ret > 0)
...@@ -3995,6 +3944,8 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf) ...@@ -3995,6 +3944,8 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf)
} }
return ret; return ret;
reject:
return iscsit_add_reject(conn, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
} }
int iscsi_target_rx_thread(void *arg) int iscsi_target_rx_thread(void *arg)
...@@ -4094,8 +4045,8 @@ int iscsi_target_rx_thread(void *arg) ...@@ -4094,8 +4045,8 @@ int iscsi_target_rx_thread(void *arg)
(!(opcode & ISCSI_OP_LOGOUT)))) { (!(opcode & ISCSI_OP_LOGOUT)))) {
pr_err("Received illegal iSCSI Opcode: 0x%02x" pr_err("Received illegal iSCSI Opcode: 0x%02x"
" while in Discovery Session, rejecting.\n", opcode); " while in Discovery Session, rejecting.\n", opcode);
iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
buffer, conn); buffer);
goto transport_err; goto transport_err;
} }
......
...@@ -15,7 +15,7 @@ extern struct iscsi_np *iscsit_add_np(struct __kernel_sockaddr_storage *, ...@@ -15,7 +15,7 @@ extern struct iscsi_np *iscsit_add_np(struct __kernel_sockaddr_storage *,
extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *, extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *,
struct iscsi_portal_group *); struct iscsi_portal_group *);
extern int iscsit_del_np(struct iscsi_np *); extern int iscsit_del_np(struct iscsi_np *);
extern int iscsit_add_reject_from_cmd(u8, int, int, unsigned char *, struct iscsi_cmd *); extern int iscsit_reject_cmd(struct iscsi_cmd *cmd, u8, unsigned char *);
extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *); extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *);
extern int iscsit_logout_closesession(struct iscsi_cmd *, struct iscsi_conn *); extern int iscsit_logout_closesession(struct iscsi_cmd *, struct iscsi_conn *);
extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *); extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *);
......
...@@ -132,7 +132,6 @@ enum cmd_flags_table { ...@@ -132,7 +132,6 @@ enum cmd_flags_table {
ICF_CONTIG_MEMORY = 0x00000020, ICF_CONTIG_MEMORY = 0x00000020,
ICF_ATTACHED_TO_RQUEUE = 0x00000040, ICF_ATTACHED_TO_RQUEUE = 0x00000040,
ICF_OOO_CMDSN = 0x00000080, ICF_OOO_CMDSN = 0x00000080,
ICF_REJECT_FAIL_CONN = 0x00000100,
}; };
/* struct iscsi_cmd->i_state */ /* struct iscsi_cmd->i_state */
...@@ -366,6 +365,8 @@ struct iscsi_cmd { ...@@ -366,6 +365,8 @@ struct iscsi_cmd {
u8 maxcmdsn_inc; u8 maxcmdsn_inc;
/* Immediate Unsolicited Dataout */ /* Immediate Unsolicited Dataout */
u8 unsolicited_data; u8 unsolicited_data;
/* Reject reason code */
u8 reject_reason;
/* CID contained in logout PDU when opcode == ISCSI_INIT_LOGOUT_CMND */ /* CID contained in logout PDU when opcode == ISCSI_INIT_LOGOUT_CMND */
u16 logout_cid; u16 logout_cid;
/* Command flags */ /* Command flags */
...@@ -446,7 +447,6 @@ struct iscsi_cmd { ...@@ -446,7 +447,6 @@ struct iscsi_cmd {
struct list_head datain_list; struct list_head datain_list;
/* R2T List */ /* R2T List */
struct list_head cmd_r2t_list; struct list_head cmd_r2t_list;
struct completion reject_comp;
/* Timer for DataOUT */ /* Timer for DataOUT */
struct timer_list dataout_timer; struct timer_list dataout_timer;
/* Iovecs for SCSI data payload RX/TX w/ kernel level sockets */ /* Iovecs for SCSI data payload RX/TX w/ kernel level sockets */
......
...@@ -746,13 +746,12 @@ int iscsit_check_post_dataout( ...@@ -746,13 +746,12 @@ int iscsit_check_post_dataout(
if (!conn->sess->sess_ops->ErrorRecoveryLevel) { if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
pr_err("Unable to recover from DataOUT CRC" pr_err("Unable to recover from DataOUT CRC"
" failure while ERL=0, closing session.\n"); " failure while ERL=0, closing session.\n");
iscsit_add_reject_from_cmd(ISCSI_REASON_DATA_DIGEST_ERROR, iscsit_reject_cmd(cmd, ISCSI_REASON_DATA_DIGEST_ERROR,
1, 0, buf, cmd); buf);
return DATAOUT_CANNOT_RECOVER; return DATAOUT_CANNOT_RECOVER;
} }
iscsit_add_reject_from_cmd(ISCSI_REASON_DATA_DIGEST_ERROR, iscsit_reject_cmd(cmd, ISCSI_REASON_DATA_DIGEST_ERROR, buf);
0, 0, buf, cmd);
return iscsit_dataout_post_crc_failed(cmd, buf); return iscsit_dataout_post_crc_failed(cmd, buf);
} }
} }
......
...@@ -162,9 +162,8 @@ static int iscsit_handle_r2t_snack( ...@@ -162,9 +162,8 @@ static int iscsit_handle_r2t_snack(
" protocol error.\n", cmd->init_task_tag, begrun, " protocol error.\n", cmd->init_task_tag, begrun,
(begrun + runlength), cmd->acked_data_sn); (begrun + runlength), cmd->acked_data_sn);
return iscsit_add_reject_from_cmd( return iscsit_reject_cmd(cmd,
ISCSI_REASON_PROTOCOL_ERROR, ISCSI_REASON_PROTOCOL_ERROR, buf);
1, 0, buf, cmd);
} }
if (runlength) { if (runlength) {
...@@ -173,8 +172,8 @@ static int iscsit_handle_r2t_snack( ...@@ -173,8 +172,8 @@ static int iscsit_handle_r2t_snack(
" with BegRun: 0x%08x, RunLength: 0x%08x, exceeds" " with BegRun: 0x%08x, RunLength: 0x%08x, exceeds"
" current R2TSN: 0x%08x, protocol error.\n", " current R2TSN: 0x%08x, protocol error.\n",
cmd->init_task_tag, begrun, runlength, cmd->r2t_sn); cmd->init_task_tag, begrun, runlength, cmd->r2t_sn);
return iscsit_add_reject_from_cmd( return iscsit_reject_cmd(cmd,
ISCSI_REASON_BOOKMARK_INVALID, 1, 0, buf, cmd); ISCSI_REASON_BOOKMARK_INVALID, buf);
} }
last_r2tsn = (begrun + runlength); last_r2tsn = (begrun + runlength);
} else } else
...@@ -433,8 +432,7 @@ static int iscsit_handle_recovery_datain( ...@@ -433,8 +432,7 @@ static int iscsit_handle_recovery_datain(
" protocol error.\n", cmd->init_task_tag, begrun, " protocol error.\n", cmd->init_task_tag, begrun,
(begrun + runlength), cmd->acked_data_sn); (begrun + runlength), cmd->acked_data_sn);
return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf);
1, 0, buf, cmd);
} }
/* /*
...@@ -445,14 +443,14 @@ static int iscsit_handle_recovery_datain( ...@@ -445,14 +443,14 @@ static int iscsit_handle_recovery_datain(
pr_err("Initiator requesting BegRun: 0x%08x, RunLength" pr_err("Initiator requesting BegRun: 0x%08x, RunLength"
": 0x%08x greater than maximum DataSN: 0x%08x.\n", ": 0x%08x greater than maximum DataSN: 0x%08x.\n",
begrun, runlength, (cmd->data_sn - 1)); begrun, runlength, (cmd->data_sn - 1));
return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_INVALID,
1, 0, buf, cmd); buf);
} }
dr = iscsit_allocate_datain_req(); dr = iscsit_allocate_datain_req();
if (!dr) if (!dr)
return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_NO_RESOURCES, return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1, 0, buf, cmd); buf);
dr->data_sn = dr->begrun = begrun; dr->data_sn = dr->begrun = begrun;
dr->runlength = runlength; dr->runlength = runlength;
......
...@@ -178,7 +178,6 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *conn, gfp_t gfp_mask) ...@@ -178,7 +178,6 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *conn, gfp_t gfp_mask)
INIT_LIST_HEAD(&cmd->i_conn_node); INIT_LIST_HEAD(&cmd->i_conn_node);
INIT_LIST_HEAD(&cmd->datain_list); INIT_LIST_HEAD(&cmd->datain_list);
INIT_LIST_HEAD(&cmd->cmd_r2t_list); INIT_LIST_HEAD(&cmd->cmd_r2t_list);
init_completion(&cmd->reject_comp);
spin_lock_init(&cmd->datain_lock); spin_lock_init(&cmd->datain_lock);
spin_lock_init(&cmd->dataout_timeout_lock); spin_lock_init(&cmd->dataout_timeout_lock);
spin_lock_init(&cmd->istate_lock); spin_lock_init(&cmd->istate_lock);
......
...@@ -34,8 +34,6 @@ extern void iscsit_put_transport(struct iscsit_transport *); ...@@ -34,8 +34,6 @@ extern void iscsit_put_transport(struct iscsit_transport *);
/* /*
* From iscsi_target.c * From iscsi_target.c
*/ */
extern int iscsit_add_reject_from_cmd(u8, int, int, unsigned char *,
struct iscsi_cmd *);
extern int iscsit_setup_scsi_cmd(struct iscsi_conn *, struct iscsi_cmd *, extern int iscsit_setup_scsi_cmd(struct iscsi_conn *, struct iscsi_cmd *,
unsigned char *); unsigned char *);
extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *); extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment