From 0007914f1dc1e84d26901ada2b3aa046f1de0cae Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Tue, 1 Jun 2010 11:35:27 +0000 Subject: [PATCH] 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 --- iscsi-scst/kernel/digest.c | 3 ++- iscsi-scst/kernel/iscsi.c | 6 ++---- iscsi-scst/kernel/iscsi.h | 4 ++++ iscsi-scst/kernel/nthread.c | 16 ++++++++++------ 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/iscsi-scst/kernel/digest.c b/iscsi-scst/kernel/digest.c index 7d6da1d23..f9d338e91 100644 --- a/iscsi-scst/kernel/digest.c +++ b/iscsi-scst/kernel/digest.c @@ -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); diff --git a/iscsi-scst/kernel/iscsi.c b/iscsi-scst/kernel/iscsi.c index a6b96f4d4..2d9d557ad 100644 --- a/iscsi-scst/kernel/iscsi.c +++ b/iscsi-scst/kernel/iscsi.c @@ -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; diff --git a/iscsi-scst/kernel/iscsi.h b/iscsi-scst/kernel/iscsi.h index 7c3ed3401..3cb20c4da 100644 --- a/iscsi-scst/kernel/iscsi.h +++ b/iscsi-scst/kernel/iscsi.h @@ -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); diff --git a/iscsi-scst/kernel/nthread.c b/iscsi-scst/kernel/nthread.c index b1b4e2c80..e94718bef 100644 --- a/iscsi-scst/kernel/nthread.c +++ b/iscsi-scst/kernel/nthread.c @@ -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; }