mirror of
https://github.com/SCST-project/scst.git
synced 2026-08-19 05:36:22 +00:00
TM handling fixes, part2, hopefully, final.
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@3450 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -653,6 +653,11 @@ again:
|
||||
goto cont;
|
||||
}
|
||||
}
|
||||
if (cmnd->data_out_in_data_receiving) {
|
||||
TRACE_MGMT_DBG("Aborted cmnd %p is waiting for "
|
||||
"DATA OUT data, keep waiting", cmnd);
|
||||
goto cont;
|
||||
}
|
||||
if (((cmnd == conn->read_cmnd) || (cmnd->r2t_len_to_receive != 0)) &&
|
||||
(time_after_eq(j, cmnd->write_start + ISCSI_TM_DATA_WAIT_TIMEOUT) ||
|
||||
force)) {
|
||||
|
||||
@@ -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);
|
||||
EXTRACHECKS_BUG_ON(cmnd->data_out_in_data_receiving);
|
||||
|
||||
req_del_from_write_timeout_list(cmnd);
|
||||
|
||||
@@ -625,11 +626,14 @@ static void req_cmnd_pre_release(struct iscsi_cmnd *req)
|
||||
|
||||
if (unlikely(req->hashed)) {
|
||||
/* It sometimes can happen during errors recovery */
|
||||
TRACE_MGMT_DBG("Removing req %p from hash", req);
|
||||
cmnd_remove_data_wait_hash(req);
|
||||
}
|
||||
|
||||
if (unlikely(req->cmd_req)) {
|
||||
/* It sometimes can happen during errors recovery */
|
||||
TRACE_MGMT_DBG("Putting cmd_req %p (req %p)", req->cmd_req, req);
|
||||
req->cmd_req->data_out_in_data_receiving = 0;
|
||||
cmnd_put(req->cmd_req);
|
||||
req->cmd_req = NULL;
|
||||
}
|
||||
@@ -1271,8 +1275,6 @@ 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;
|
||||
@@ -2048,8 +2050,9 @@ static int data_out_start(struct iscsi_cmnd *cmnd)
|
||||
TRACE_ENTRY();
|
||||
|
||||
/*
|
||||
* There is no race with send_r2t() and conn_abort(), since
|
||||
* all functions called from single read thread
|
||||
* There is no race with send_r2t(), conn_abort() and
|
||||
* iscsi_check_tm_data_wait_timeouts(), since
|
||||
* all the functions called from single read thread
|
||||
*/
|
||||
iscsi_extracheck_is_rd_thread(cmnd->conn);
|
||||
|
||||
@@ -2069,6 +2072,8 @@ static int data_out_start(struct iscsi_cmnd *cmnd)
|
||||
goto out;
|
||||
}
|
||||
|
||||
cmnd_get(orig_req);
|
||||
|
||||
if (unlikely(orig_req->r2t_len_to_receive < cmnd->pdu.datasize)) {
|
||||
if (orig_req->prelim_compl_flags != 0) {
|
||||
/* We can have fake r2t_len_to_receive */
|
||||
@@ -2102,6 +2107,9 @@ go:
|
||||
goto out;
|
||||
}
|
||||
|
||||
EXTRACHECKS_BUG_ON(orig_req->data_out_in_data_receiving);
|
||||
orig_req->data_out_in_data_receiving = 1;
|
||||
|
||||
TRACE_WRITE("cmnd %p, orig_req %p, offset %u, datasize %u", cmnd,
|
||||
orig_req, offset, cmnd->pdu.datasize);
|
||||
|
||||
@@ -2129,6 +2137,8 @@ static void data_out_end(struct iscsi_cmnd *cmnd)
|
||||
|
||||
iscsi_extracheck_is_rd_thread(cmnd->conn);
|
||||
|
||||
req->data_out_in_data_receiving = 0;
|
||||
|
||||
if (!(cmnd->conn->ddigest_type & DIGEST_NONE) &&
|
||||
!cmnd->ddigest_checked) {
|
||||
cmd_add_on_rx_ddigest_list(req, cmnd);
|
||||
@@ -2968,9 +2978,9 @@ static void iscsi_push_cmnd(struct iscsi_cmnd *cmnd)
|
||||
|
||||
if (unlikely(before(cmd_sn, session->exp_cmd_sn))) {
|
||||
TRACE_MGMT_DBG("Ignoring out of expected range cmd_sn "
|
||||
"(sn %u, exp_sn %u, op %x, CDB op %x)", cmd_sn,
|
||||
session->exp_cmd_sn, cmnd_opcode(cmnd),
|
||||
cmnd_scsicode(cmnd));
|
||||
"(sn %u, exp_sn %u, cmd %p, op %x, CDB op %x)",
|
||||
cmd_sn, session->exp_cmd_sn, cmnd,
|
||||
cmnd_opcode(cmnd), cmnd_scsicode(cmnd));
|
||||
drop = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -393,6 +393,13 @@ struct iscsi_cmnd {
|
||||
unsigned int force_cleanup_done:1;
|
||||
unsigned int dec_active_cmds:1;
|
||||
unsigned int ddigest_checked:1;
|
||||
/*
|
||||
* Used to prevent release of original req while its related DATA OUT
|
||||
* cmd is receiving data, i.e. stays between data_out_start() and
|
||||
* data_out_end(). Ref counting can't be used for that, because
|
||||
* req_cmnd_release() supposed to be called only once.
|
||||
*/
|
||||
unsigned int data_out_in_data_receiving:1;
|
||||
#ifdef CONFIG_SCST_EXTRACHECKS
|
||||
unsigned int on_rx_digest_list:1;
|
||||
unsigned int release_called:1;
|
||||
|
||||
Reference in New Issue
Block a user