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: Santosh Kulkarni <santosh.kulkarni@calsoftinc.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
04f3b31bff
commit
ea7e32bec1
@ -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
|
|||||||
*/
|
*/
|
||||||
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,
|
|||||||
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user