We need to abort internal commands as well.

git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@4470 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2012-08-16 19:52:32 +00:00
parent 5305d716ea
commit 5b26b06791
3 changed files with 31 additions and 11 deletions

View File

@@ -4473,6 +4473,7 @@ static struct scst_cmd *scst_create_prepare_internal_cmd(
struct scst_cmd *res;
int rc;
gfp_t gfp_mask = scst_cmd_atomic(orig_cmd) ? GFP_ATOMIC : GFP_KERNEL;
unsigned long flags;
TRACE_ENTRY();
@@ -4494,6 +4495,17 @@ static struct scst_cmd *scst_create_prepare_internal_cmd(
res->queue_type = queue_type;
res->data_direction = SCST_DATA_UNKNOWN;
/*
* We need to keep it here to be able to abort during TM processing.
* They should be aborted to (1) speed up TM processing and (2) to
* guarantee that after a TM command finished the affected device(s)
* is/are in a quiescent state with all affected commands finished and
* others - blocked.
*/
spin_lock_irqsave(&res->sess->sess_list_lock, flags);
list_add_tail(&res->sess_cmd_list_entry, &res->sess->sess_cmd_list);
spin_unlock_irqrestore(&res->sess->sess_list_lock, flags);
scst_sess_get(res->sess);
if (res->tgt_dev != NULL)
res->cpu_cmd_counter = scst_get();
@@ -4926,6 +4938,7 @@ EXPORT_SYMBOL_GPL(scst_write_same);
int scst_finish_internal_cmd(struct scst_cmd *cmd)
{
int res;
unsigned long flags;
TRACE_ENTRY();
@@ -4938,6 +4951,17 @@ int scst_finish_internal_cmd(struct scst_cmd *cmd)
goto out;
}
spin_lock_irqsave(&cmd->sess->sess_list_lock, flags);
list_del(&cmd->sess_cmd_list_entry);
cmd->done = 1;
cmd->finished = 1;
spin_unlock_irqrestore(&cmd->sess->sess_list_lock, flags);
if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) {
scst_done_cmd_mgmt(cmd);
scst_finish_cmd_mgmt(cmd);
}
if (cmd->cdb[0] == REQUEST_SENSE)
scst_complete_request_sense(cmd);
else {

View File

@@ -394,6 +394,7 @@ uint64_t scst_unpack_lun(const uint8_t *lun, int len);
struct scst_mgmt_cmd *scst_alloc_mgmt_cmd(gfp_t gfp_mask);
void scst_free_mgmt_cmd(struct scst_mgmt_cmd *mcmd);
void scst_done_cmd_mgmt(struct scst_cmd *cmd);
void scst_finish_cmd_mgmt(struct scst_cmd *cmd);
static inline void scst_devt_cleanup(struct scst_dev_type *devt) { }

View File

@@ -45,7 +45,6 @@
static void scst_cmd_set_sn(struct scst_cmd *cmd);
static int __scst_init_cmd(struct scst_cmd *cmd);
static void scst_finish_cmd_mgmt(struct scst_cmd *cmd);
static struct scst_cmd *__scst_find_cmd_by_tag(struct scst_session *sess,
uint64_t tag, bool to_abort);
static void scst_process_redirect_cmd(struct scst_cmd *cmd,
@@ -4703,7 +4702,7 @@ void scst_async_mcmd_completed(struct scst_mgmt_cmd *mcmd, int status)
EXPORT_SYMBOL_GPL(scst_async_mcmd_completed);
/* No locks */
static void scst_finish_cmd_mgmt(struct scst_cmd *cmd)
void scst_finish_cmd_mgmt(struct scst_cmd *cmd)
{
struct scst_mgmt_cmd_stub *mstb, *t;
bool wake = false;
@@ -4846,9 +4845,6 @@ void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd,
*/
smp_mb__after_set_bit();
if (cmd->internal)
goto out;
if (cmd->tgt_dev == NULL) {
spin_lock_irqsave(&scst_init_lock, flags);
scst_init_poll_cnt++;
@@ -4909,12 +4905,12 @@ void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd,
"sn %u) being executed/xmitted (state %d, "
"op %x, proc time %ld sec., timeout %d sec.), "
"deferring ABORT (cmd_done_wait_count %d, "
"cmd_finish_wait_count %d)", cmd,
"cmd_finish_wait_count %d, internal %d)", cmd,
(long long unsigned int)cmd->tag,
cmd->sn, cmd->state, cmd->cdb[0],
(long)(jiffies - cmd->start_time) / HZ,
cmd->timeout / HZ, mcmd->cmd_done_wait_count,
mcmd->cmd_finish_wait_count);
mcmd->cmd_finish_wait_count, cmd->internal);
/*
* cmd can't die here or sess_list_lock already taken
* and cmd is in the sess list
@@ -4926,14 +4922,13 @@ void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd,
mempool_free(mstb, scst_mgmt_stub_mempool);
}
if (cmd->tgtt->on_abort_cmd)
if (!cmd->internal && cmd->tgtt->on_abort_cmd)
cmd->tgtt->on_abort_cmd(cmd);
}
unlock:
spin_unlock_irqrestore(&scst_mcmd_lock, flags);
out:
tm_dbg_release_cmd(cmd);
TRACE_EXIT();
@@ -6894,7 +6889,7 @@ static struct scst_cmd *__scst_find_cmd_by_tag(struct scst_session *sess,
list_for_each_entry(cmd, &sess->sess_cmd_list,
sess_cmd_list_entry) {
if (cmd->tag == tag) {
if ((cmd->tag == tag) && likely(!cmd->internal)) {
/*
* We must not count done commands, because
* they were submitted for transmission.
@@ -6965,7 +6960,7 @@ struct scst_cmd *scst_find_cmd(struct scst_session *sess, void *data,
*/
if (cmd->done)
continue;
if (cmp_fn(cmd, data))
if (cmp_fn(cmd, data) && likely(!cmd->internal))
goto out_unlock;
}