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:
Vladislav Bolkhovitin
2010-06-01 11:35:27 +00:00
parent 6dca03e5d2
commit 0007914f1d
4 changed files with 18 additions and 11 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
}