Commit ea7e32be authored by Nicholas Bellinger's avatar Nicholas Bellinger

iscsi-target: Do not reject non-immediate CmdSNs exceeding MaxCmdSN

This patch changes iscsit_sequence_cmd() logic to no longer reject
non-immediate CmdSNs that exceed MaxCmdSN with a protocol error,
but instead silently ignore them.

This is done to correctly follow RFC-3720 Section 3.2.2.1:

   For non-immediate commands, the CmdSN field can take any
   value from ExpCmdSN to MaxCmdSN inclusive.  The target MUST silently
   ignore any non-immediate command outside of this range or non-
   immediate duplicates within the range.
Reported-by: default avatarSantosh Kulkarni <santosh.kulkarni@calsoftinc.com>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent 04f3b31b
...@@ -193,6 +193,7 @@ enum recover_cmdsn_ret_table { ...@@ -193,6 +193,7 @@ enum recover_cmdsn_ret_table {
CMDSN_NORMAL_OPERATION = 0, CMDSN_NORMAL_OPERATION = 0,
CMDSN_LOWER_THAN_EXP = 1, CMDSN_LOWER_THAN_EXP = 1,
CMDSN_HIGHER_THAN_EXP = 2, CMDSN_HIGHER_THAN_EXP = 2,
CMDSN_MAXCMDSN_OVERRUN = 3,
}; };
/* Used for iscsi_handle_immediate_data() return values */ /* Used for iscsi_handle_immediate_data() return values */
......
...@@ -242,9 +242,9 @@ static inline int iscsit_check_received_cmdsn(struct iscsi_session *sess, u32 cm ...@@ -242,9 +242,9 @@ static inline int iscsit_check_received_cmdsn(struct iscsi_session *sess, u32 cm
*/ */
if (iscsi_sna_gt(cmdsn, sess->max_cmd_sn)) { if (iscsi_sna_gt(cmdsn, sess->max_cmd_sn)) {
pr_err("Received CmdSN: 0x%08x is greater than" pr_err("Received CmdSN: 0x%08x is greater than"
" MaxCmdSN: 0x%08x, protocol error.\n", cmdsn, " MaxCmdSN: 0x%08x, ignoring.\n", cmdsn,
sess->max_cmd_sn); sess->max_cmd_sn);
ret = CMDSN_ERROR_CANNOT_RECOVER; ret = CMDSN_MAXCMDSN_OVERRUN;
} else if (cmdsn == sess->exp_cmd_sn) { } else if (cmdsn == sess->exp_cmd_sn) {
sess->exp_cmd_sn++; sess->exp_cmd_sn++;
...@@ -303,14 +303,16 @@ int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ...@@ -303,14 +303,16 @@ int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
ret = CMDSN_HIGHER_THAN_EXP; ret = CMDSN_HIGHER_THAN_EXP;
break; break;
case CMDSN_LOWER_THAN_EXP: case CMDSN_LOWER_THAN_EXP:
case CMDSN_MAXCMDSN_OVERRUN:
default:
cmd->i_state = ISTATE_REMOVE; cmd->i_state = ISTATE_REMOVE;
iscsit_add_cmd_to_immediate_queue(cmd, conn, cmd->i_state); iscsit_add_cmd_to_immediate_queue(cmd, conn, cmd->i_state);
ret = cmdsn_ret; /*
break; * Existing callers for iscsit_sequence_cmd() will silently
default: * ignore commands with CMDSN_LOWER_THAN_EXP, so force this
reason = ISCSI_REASON_PROTOCOL_ERROR; * return for CMDSN_MAXCMDSN_OVERRUN as well..
reject = true; */
ret = cmdsn_ret; ret = CMDSN_LOWER_THAN_EXP;
break; break;
} }
mutex_unlock(&conn->sess->cmdsn_mutex); mutex_unlock(&conn->sess->cmdsn_mutex);
......
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