mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-23 21:51:27 +00:00
Make RX data digest failures handling more smart
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1731 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -188,7 +188,8 @@ int digest_rx_data(struct iscsi_cmnd *cmnd)
|
||||
cmnd->conn->rpadding);
|
||||
|
||||
if (unlikely(crc != cmnd->ddigest)) {
|
||||
PRINT_ERROR("%s", "RX data digest failed");
|
||||
TRACE(TRACE_MINOR|TRACE_MGMT_DEBUG, "%s", "RX data digest "
|
||||
"failed");
|
||||
TRACE_MGMT_DBG("Calculated crc %x, ddigest %x, offset %d", crc,
|
||||
cmnd->ddigest, offset);
|
||||
iscsi_dump_pdu(&cmnd->pdu);
|
||||
|
||||
@@ -69,8 +69,6 @@ static void cmnd_remove_data_wait_hash(struct iscsi_cmnd *cmnd);
|
||||
static void iscsi_send_task_mgmt_resp(struct iscsi_cmnd *req, int status);
|
||||
static void iscsi_check_send_delayed_tm_resp(struct iscsi_session *sess);
|
||||
static void req_cmnd_release(struct iscsi_cmnd *req);
|
||||
static int iscsi_preliminary_complete(struct iscsi_cmnd *req,
|
||||
struct iscsi_cmnd *orig_req, bool get_data);
|
||||
static int cmnd_insert_data_wait_hash(struct iscsi_cmnd *cmnd);
|
||||
static void __cmnd_abort(struct iscsi_cmnd *cmnd);
|
||||
static void iscsi_set_resid(struct iscsi_cmnd *rsp, bool bufflen_set);
|
||||
@@ -943,7 +941,7 @@ out:
|
||||
return res;
|
||||
}
|
||||
|
||||
static int set_scst_preliminary_status_rsp(struct iscsi_cmnd *req,
|
||||
int set_scst_preliminary_status_rsp(struct iscsi_cmnd *req,
|
||||
bool get_data, int key, int asc, int ascq)
|
||||
{
|
||||
int res = 0;
|
||||
@@ -1334,7 +1332,7 @@ static void iscsi_set_resid(struct iscsi_cmnd *rsp, bool bufflen_set)
|
||||
return;
|
||||
}
|
||||
|
||||
static int iscsi_preliminary_complete(struct iscsi_cmnd *req,
|
||||
int iscsi_preliminary_complete(struct iscsi_cmnd *req,
|
||||
struct iscsi_cmnd *orig_req, bool get_data)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
@@ -487,6 +487,10 @@ extern void conn_abort(struct iscsi_conn *conn);
|
||||
extern void iscsi_restart_cmnd(struct iscsi_cmnd *cmnd);
|
||||
extern void iscsi_fail_data_waiting_cmnd(struct iscsi_cmnd *cmnd);
|
||||
extern void iscsi_send_nop_in(struct iscsi_conn *conn);
|
||||
extern int iscsi_preliminary_complete(struct iscsi_cmnd *req,
|
||||
struct iscsi_cmnd *orig_req, bool get_data);
|
||||
extern int set_scst_preliminary_status_rsp(struct iscsi_cmnd *req,
|
||||
bool get_data, int key, int asc, int ascq);
|
||||
|
||||
/* conn.c */
|
||||
extern struct iscsi_conn *conn_lookup(struct iscsi_session *, u16);
|
||||
|
||||
@@ -776,8 +776,13 @@ static int iscsi_rx_check_ddigest(struct iscsi_conn *conn)
|
||||
cmnd->ddigest_checked = 1;
|
||||
res = digest_rx_data(cmnd);
|
||||
if (unlikely(res != 0)) {
|
||||
mark_conn_closed(conn);
|
||||
goto out;
|
||||
if (unlikely(cmnd->scst_cmd == NULL)) {
|
||||
/* Just drop it */
|
||||
iscsi_preliminary_complete(cmnd, cmnd, false);
|
||||
} else
|
||||
set_scst_preliminary_status_rsp(cmnd, false,
|
||||
SCST_LOAD_SENSE(iscsi_sense_crc_error));
|
||||
res = 0;
|
||||
}
|
||||
} else if (cmnd_opcode(cmnd) == ISCSI_OP_SCSI_CMD) {
|
||||
cmd_add_on_rx_ddigest_list(cmnd, cmnd);
|
||||
@@ -786,19 +791,18 @@ static int iscsi_rx_check_ddigest(struct iscsi_conn *conn)
|
||||
/*
|
||||
* We could get here only for Nop-Out. ISCSI RFC
|
||||
* doesn't specify how to deal with digest errors in
|
||||
* this case. Is closing connection correct?
|
||||
* this case. Let's just drop the command.
|
||||
*/
|
||||
TRACE_DBG("cmnd %p, opcode %x: checking NOP RX "
|
||||
"ddigest", cmnd, cmnd_opcode(cmnd));
|
||||
res = digest_rx_data(cmnd);
|
||||
if (unlikely(res != 0)) {
|
||||
mark_conn_closed(conn);
|
||||
goto out;
|
||||
iscsi_preliminary_complete(cmnd, cmnd, false);
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user