diff --git a/iscsi-scst/kernel/iscsi.c b/iscsi-scst/kernel/iscsi.c index 9355ebceb..e57bfab0c 100644 --- a/iscsi-scst/kernel/iscsi.c +++ b/iscsi-scst/kernel/iscsi.c @@ -417,6 +417,7 @@ void cmnd_done(struct iscsi_cmnd *cmnd) EXTRACHECKS_BUG_ON(cmnd->on_rx_digest_list); EXTRACHECKS_BUG_ON(cmnd->hashed); + EXTRACHECKS_BUG_ON(cmnd->cmd_req); req_del_from_write_timeout_list(cmnd); @@ -628,6 +629,12 @@ static void req_cmnd_pre_release(struct iscsi_cmnd *req) cmnd_remove_data_wait_hash(req); } + if (unlikely(req->cmd_req)) { + /* It sometimes can happen during errors recovery */ + cmnd_put(req->cmd_req); + req->cmd_req = NULL; + } + if (unlikely(req->main_rsp != NULL)) { TRACE_DBG("Sending main rsp %p", req->main_rsp); if (cmnd_opcode(req) == ISCSI_OP_SCSI_CMD) { @@ -1265,6 +1272,8 @@ static struct iscsi_cmnd *cmnd_find_data_wait_hash(struct iscsi_conn *conn, spin_lock(&session->cmnd_data_wait_hash_lock); res = __cmnd_find_data_wait_hash(conn, itt); + if (cmnd_get_check(res) != 0) + res = NULL; spin_unlock(&session->cmnd_data_wait_hash_lock); return res; @@ -2158,7 +2167,7 @@ static void data_out_end(struct iscsi_cmnd *cmnd) req->r2t_len_to_send); if (!(req_hdr->flags & ISCSI_FLG_FINAL)) - goto out; + goto out_put; if (req->r2t_len_to_receive == 0) { if (!req->pending) @@ -2166,6 +2175,10 @@ static void data_out_end(struct iscsi_cmnd *cmnd) } else if (req->r2t_len_to_send != 0) send_r2t(req); +out_put: + cmnd_put(req); + cmnd->cmd_req = NULL; + out: TRACE_EXIT(); return;