- Fixes commands leak in case of, e.g., QUEUE FULL status returned, because of uninitialised cmd->sn.

- HEAD OF QUEUE commands processing simplified to fix known problems
 - Cosmetics 


git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@198 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2007-09-25 09:46:36 +00:00
parent c5469e6126
commit a61f896dd3
7 changed files with 126 additions and 168 deletions

View File

@@ -341,9 +341,6 @@
/* Set if tgt_dev is RESERVED by another session */
#define SCST_TGT_DEV_RESERVED 1
/* Set HEAD OF QUEUE cmd is being executed */
#define SCST_TGT_DEV_HQ_ACTIVE 2
/* Set if the corresponding context is atomic */
#define SCST_TGT_DEV_AFTER_INIT_WR_ATOMIC 5
#define SCST_TGT_DEV_AFTER_INIT_OTH_ATOMIC 6
@@ -658,7 +655,7 @@ struct scst_dev_type
/* Set, if no /proc files should be automatically created by SCST */
unsigned no_proc:1;
/* Set if expected_sn in cmd->scst_cmd_done() */
/* Set if increment expected_sn in cmd->scst_cmd_done() */
unsigned inc_expected_sn_on_done:1;
/*
@@ -1027,11 +1024,14 @@ struct scst_cmd
*/
unsigned int preprocessing_only:1;
/* Set if scst_cmd_set_sn() was called */
unsigned int sn_set:1;
/*
* Set if scst_cmd_init_stage1_done() called and the target want
* that the SN for the cmd isn't assigned until scst_restart_cmd()
* Set if scst_cmd_init_stage1_done() called and the target wants
* that the SN for the cmd won't be assigned until scst_restart_cmd()
*/
unsigned int no_sn:1;
unsigned int set_sn_on_restart_cmd:1;
/* Set if the cmd's must not use sgv cache for data buffer */
unsigned int no_sgv:1;
@@ -1053,8 +1053,8 @@ struct scst_cmd
unsigned int skip_parse:1;
/*
* Set if inc expected_sn in cmd->scst_cmd_done() (to
* save extra dereferences)
* Set if increment expected_sn in cmd->scst_cmd_done() (to save
* extra dereferences)
*/
unsigned int inc_expected_sn_on_done:1;
@@ -1366,10 +1366,11 @@ struct scst_tgt_dev
*/
int def_cmd_count;
spinlock_t sn_lock;
unsigned long expected_sn, curr_sn;
unsigned long expected_sn;
unsigned long curr_sn;
int hq_cmd_count;
struct list_head deferred_cmd_list;
struct list_head skipped_sn_list;
struct list_head hq_cmd_list;
/*
* Set if the prev cmd was ORDERED. Size must allow unprotected
@@ -1508,10 +1509,9 @@ void scst_unregister_target_template(struct scst_tgt_template *vtt);
* Registers and returns target adapter
* Returns new target structure on success or NULL otherwise.
*
* If parameter "target_name" isn't NULL, then new security group with name
* "Default_##target_name" will be created and all sessions, which don't
* belong to any defined security groups, will be assigned to it instead of
* the "Default" one.
* If parameter "target_name" isn't NULL, then security group with name
* "Default_##target_name", if created, will be used as the default
* instead of "Default" one for all initiators not assigned to any other group.
*/
struct scst_tgt *scst_register(struct scst_tgt_template *vtt,
const char *target_name);
@@ -1630,9 +1630,10 @@ struct scst_cmd *scst_rx_cmd(struct scst_session *sess,
*
* !!IMPORTANT!!
*
* If cmd->no_sn not set, this function, as well as scst_cmd_init_stage1_done()
* and scst_restart_cmd() must not be called simultaneously for the same session
* (more precisely, for the same session/LUN, i.e. tgt_dev), i.e. they must be
* If cmd->set_sn_on_restart_cmd not set, this function, as well as
* scst_cmd_init_stage1_done() and scst_restart_cmd(), must not be
* called simultaneously for the same session (more precisely,
* for the same session/LUN, i.e. tgt_dev), i.e. they must be
* somehow externally serialized. This is needed to have lock free fast path in
* scst_cmd_set_sn(). For majority of targets those functions are naturally
* serialized by the single source of commands. Only iSCSI immediate commands
@@ -1654,7 +1655,7 @@ static inline void scst_cmd_init_stage1_done(struct scst_cmd *cmd,
int pref_context, int set_sn)
{
cmd->preprocessing_only = 1;
cmd->no_sn = !set_sn;
cmd->set_sn_on_restart_cmd = !set_sn;
scst_cmd_init_done(cmd, pref_context);
}

View File

@@ -2092,6 +2092,7 @@ static int dev_user_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
int res, rc;
struct dev_user_cmd *ucmd;
struct scst_user_dev *dev = (struct scst_user_dev*)tgt_dev->dev->dh_priv;
struct dev_user_cmd *ucmd_to_abort = NULL;
TRACE_ENTRY();
@@ -2107,15 +2108,15 @@ static int dev_user_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
ucmd->user_cmd.tm_cmd.fn = mcmd->fn;
if (mcmd->cmd_to_abort != NULL) {
struct dev_user_cmd *ucmd_to_abort =
(struct dev_user_cmd*)mcmd->cmd_to_abort->dh_priv;
ucmd_to_abort = (struct dev_user_cmd*)mcmd->cmd_to_abort->dh_priv;
if (ucmd_to_abort != NULL)
ucmd->user_cmd.tm_cmd.cmd_h_to_abort = ucmd_to_abort->h;
}
TRACE_MGMT_DBG("Preparing TM ucmd %p (h %d, fn %d, cmd_to_abort %p, "
"ucmd_to_abort %d)", ucmd, ucmd->h, mcmd->fn,
mcmd->cmd_to_abort, ucmd->user_cmd.tm_cmd.cmd_h_to_abort);
"ucmd_to_abort %p, cmd_h_to_abort %d)", ucmd, ucmd->h,
mcmd->fn, mcmd->cmd_to_abort, ucmd_to_abort,
ucmd->user_cmd.tm_cmd.cmd_h_to_abort);
ucmd->state = UCMD_STATE_TM_EXECING;
@@ -2158,6 +2159,7 @@ static int dev_user_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
sBUG_ON(irqs_disabled());
spin_lock_irq(&dev->cmd_lists.cmd_list_lock);
out_locked_free:
kfree(ucmd->cmpl);
ucmd->cmpl = NULL;

View File

@@ -651,6 +651,17 @@ static int vdisk_do_job(struct scst_cmd *cmd)
TRACE_ENTRY();
switch(cmd->queue_type) {
case SCST_CMD_QUEUE_ORDERED:
TRACE(TRACE_ORDER, "ORDERED cmd %p", cmd);
break;
case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
TRACE(TRACE_ORDER, "HQ cmd %p", cmd);
break;
default:
break;
}
rc = scst_check_local_events(cmd);
if (unlikely(rc != 0))
goto out_done;

View File

@@ -404,7 +404,6 @@ static struct scst_tgt_dev *scst_alloc_add_tgt_dev(struct scst_session *sess,
spin_lock_init(&tgt_dev->sn_lock);
INIT_LIST_HEAD(&tgt_dev->deferred_cmd_list);
INIT_LIST_HEAD(&tgt_dev->skipped_sn_list);
INIT_LIST_HEAD(&tgt_dev->hq_cmd_list);
tgt_dev->expected_sn = 1;
tgt_dev->num_free_sn_slots = ARRAY_SIZE(tgt_dev->sn_slots);
tgt_dev->cur_sn_slot = &tgt_dev->sn_slots[0];
@@ -2427,47 +2426,6 @@ void scst_free_all_UA(struct scst_tgt_dev *tgt_dev)
return;
}
/* sn_lock supposed to be held and IRQ off */
static inline int __scst_check_hq_cmd(struct scst_cmd *cmd)
{
struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
struct scst_cmd *hq;
int res;
TRACE_ENTRY();
/* According to SAM, the latest HQ cmd shall pass first */
hq = list_entry(tgt_dev->hq_cmd_list.next, typeof(*hq),
sn_cmd_list_entry);
if ((cmd == hq) && !test_bit(SCST_TGT_DEV_HQ_ACTIVE,
&tgt_dev->tgt_dev_flags)) {
TRACE_SN("Passing HQ cmd %p", cmd);
res = 1;
list_del(&cmd->sn_cmd_list_entry);
set_bit(SCST_TGT_DEV_HQ_ACTIVE, &tgt_dev->tgt_dev_flags);
} else {
TRACE_SN("Defer HQ cmd %p", cmd);
res = 0;
cmd->hq_deferred = 1;
tgt_dev->def_cmd_count++;
}
TRACE_EXIT_RES(res);
return res;
}
int scst_check_hq_cmd(struct scst_cmd *cmd)
{
struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
int res;
spin_lock_irq(&tgt_dev->sn_lock);
res = __scst_check_hq_cmd(cmd);
spin_unlock_irq(&tgt_dev->sn_lock);
return res;
}
/* No locks */
struct scst_cmd *__scst_check_deferred_commands(struct scst_tgt_dev *tgt_dev)
{
@@ -2476,38 +2434,14 @@ struct scst_cmd *__scst_check_deferred_commands(struct scst_tgt_dev *tgt_dev)
spin_lock_irq(&tgt_dev->sn_lock);
if (unlikely(test_bit(SCST_TGT_DEV_HQ_ACTIVE, &tgt_dev->tgt_dev_flags))) {
if (!list_empty(&tgt_dev->hq_cmd_list)) {
int rc;
cmd = list_entry(tgt_dev->hq_cmd_list.next,
typeof(*cmd), sn_cmd_list_entry);
if (cmd->hq_deferred) {
TRACE_SN("Releasing deferred HQ cmd %p", cmd);
tgt_dev->def_cmd_count--;
cmd->hq_deferred = 0;
res = cmd;
/*
* Since __scst_check_hq_cmd() is inline, a lot
* of code should be optimized out
*/
clear_bit(SCST_TGT_DEV_HQ_ACTIVE,
&tgt_dev->tgt_dev_flags);
rc = __scst_check_hq_cmd(res);
EXTRACHECKS_BUG_ON(rc != 1);
goto out_unlock;
}
}
TRACE_SN("Turning OFF hq_cmd_active (tgt_dev %p)",
tgt_dev);
clear_bit(SCST_TGT_DEV_HQ_ACTIVE, &tgt_dev->tgt_dev_flags);
}
restart:
list_for_each_entry_safe(cmd, t, &tgt_dev->deferred_cmd_list,
sn_cmd_list_entry) {
EXTRACHECKS_BUG_ON(cmd->queue_type ==
SCST_CMD_QUEUE_HEAD_OF_QUEUE);
if (cmd->sn == expected_sn) {
TRACE_SN("Deferred command %p (sn %ld) found",
cmd, cmd->sn);
TRACE_SN("Deferred command %p (sn %ld, set %d) found",
cmd, cmd->sn, cmd->sn_set);
tgt_dev->def_cmd_count--;
list_del(&cmd->sn_cmd_list_entry);
if (res == NULL)
@@ -2528,6 +2462,8 @@ restart:
list_for_each_entry(cmd, &tgt_dev->skipped_sn_list,
sn_cmd_list_entry) {
EXTRACHECKS_BUG_ON(cmd->queue_type ==
SCST_CMD_QUEUE_HEAD_OF_QUEUE);
if (cmd->sn == expected_sn) {
atomic_t *slot = cmd->sn_slot;
/*
@@ -2540,8 +2476,6 @@ restart:
tgt_dev->def_cmd_count--;
list_del(&cmd->sn_cmd_list_entry);
spin_unlock_irq(&tgt_dev->sn_lock);
EXTRACHECKS_BUG_ON(cmd->queue_type ==
SCST_CMD_QUEUE_HEAD_OF_QUEUE);
if (test_and_set_bit(SCST_CMD_CAN_BE_DESTROYED,
&cmd->cmd_flags)) {
scst_destroy_put_cmd(cmd);
@@ -2833,13 +2767,9 @@ static struct scst_cmd *__scst_unblock_deferred(
{
struct scst_cmd *res = NULL;
if (out_of_sn_cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE) {
TRACE_SN("HQ out_of_sn_cmd %p", out_of_sn_cmd);
spin_lock_irq(&out_of_sn_cmd->tgt_dev->sn_lock);
list_del(&out_of_sn_cmd->sn_cmd_list_entry);
spin_unlock_irq(&out_of_sn_cmd->tgt_dev->sn_lock);
res = scst_check_deferred_commands(tgt_dev);
} else if (out_of_sn_cmd->sn == tgt_dev->expected_sn) {
EXTRACHECKS_BUG_ON(!out_of_sn_cmd->sn_set);
if (out_of_sn_cmd->sn == tgt_dev->expected_sn) {
scst_inc_expected_sn(tgt_dev, out_of_sn_cmd->sn_slot);
res = scst_check_deferred_commands(tgt_dev);
} else {
@@ -2864,8 +2794,8 @@ void scst_unblock_deferred(struct scst_tgt_dev *tgt_dev,
TRACE_ENTRY();
if (out_of_sn_cmd->no_sn) {
TRACE_SN("cmd %p with no_sn", out_of_sn_cmd);
if (!out_of_sn_cmd->sn_set) {
TRACE_SN("cmd %p without sn", out_of_sn_cmd);
goto out;
}

View File

@@ -90,9 +90,6 @@ extern unsigned long scst_trace_flag;
/* Set if a TM command is being performed */
#define SCST_FLAG_TM_ACTIVE 2
/* Set if scst_cmd_mem_work is scheduled */
#define SCST_FLAG_CMD_MEM_WORK_SCHEDULED 3
/**
** Return codes for cmd state process functions
**/
@@ -222,8 +219,7 @@ extern struct scst_cmd *__scst_check_deferred_commands(
static inline struct scst_cmd *scst_check_deferred_commands(
struct scst_tgt_dev *tgt_dev)
{
if ((tgt_dev->def_cmd_count == 0) &&
likely(!test_bit(SCST_TGT_DEV_HQ_ACTIVE, &tgt_dev->tgt_dev_flags)))
if (tgt_dev->def_cmd_count == 0)
return NULL;
else
return __scst_check_deferred_commands(tgt_dev);

View File

@@ -634,7 +634,7 @@ void scst_restart_cmd(struct scst_cmd *cmd, int status, int pref_context)
cmd->state = SCST_CMD_STATE_PRE_EXEC;
break;
}
if (cmd->no_sn)
if (cmd->set_sn_on_restart_cmd)
scst_cmd_set_sn(cmd);
/* Small context optimization */
if ((pref_context == SCST_CONTEXT_TASKLET) ||
@@ -955,8 +955,9 @@ static void scst_inc_check_expected_sn(struct scst_cmd *cmd)
{
struct scst_cmd *c;
if (likely(cmd->queue_type != SCST_CMD_QUEUE_HEAD_OF_QUEUE))
if (likely(cmd->sn_set))
scst_inc_expected_sn(cmd->tgt_dev, cmd->sn_slot);
c = scst_check_deferred_commands(cmd->tgt_dev);
if (c != NULL) {
unsigned long flags;
@@ -1813,42 +1814,27 @@ static int scst_send_to_midlev(struct scst_cmd *cmd)
"thread context, rescheduling");
res = SCST_CMD_STATE_RES_NEED_THREAD;
scst_dec_on_dev_cmd(cmd);
goto out_dec_cmd_count;
goto out_put;
} else {
sBUG_ON(rc != SCST_EXEC_COMPLETED);
goto out_unplug;
}
}
EXTRACHECKS_BUG_ON(cmd->no_sn);
if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE))
goto exec;
if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE)) {
/*
* W/o get() there will be a race, when cmd is executed and
* destroyed before "goto out_unplug"
*/
scst_cmd_get(cmd);
if (scst_check_hq_cmd(cmd)) {
scst_cmd_put(cmd);
goto exec;
} else {
scst_dec_on_dev_cmd(cmd);
scst_cmd_put(cmd);
goto out_unplug;
}
}
sBUG_ON(!cmd->sn_set);
expected_sn = tgt_dev->expected_sn;
/* Optimized for lockless fast path */
if ((cmd->sn != expected_sn) || unlikely(test_bit(SCST_TGT_DEV_HQ_ACTIVE,
&tgt_dev->tgt_dev_flags))) {
if ((cmd->sn != expected_sn) || (tgt_dev->hq_cmd_count > 0)) {
spin_lock_irq(&tgt_dev->sn_lock);
tgt_dev->def_cmd_count++;
smp_mb();
barrier(); /* to reread expected_sn & hq_cmd_active */
barrier(); /* to reread expected_sn & hq_cmd_count */
expected_sn = tgt_dev->expected_sn;
if ((cmd->sn != expected_sn) || test_bit(SCST_TGT_DEV_HQ_ACTIVE,
&tgt_dev->tgt_dev_flags)) {
if ((cmd->sn != expected_sn) || (tgt_dev->hq_cmd_count > 0)) {
/* We are under IRQ lock, but dev->dev_lock is BH one */
int cmd_blocking = scst_pre_dec_on_dev_cmd(cmd);
if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) {
@@ -1859,18 +1845,16 @@ static int scst_send_to_midlev(struct scst_cmd *cmd)
cmd->state = SCST_CMD_STATE_DEV_DONE;
res = SCST_CMD_STATE_RES_CONT_SAME;
} else {
TRACE_SN("Deferring cmd %p (sn=%ld, "
"expected_sn=%ld, hq_cmd_active=%d)", cmd,
cmd->sn, expected_sn,
test_bit(SCST_TGT_DEV_HQ_ACTIVE,
&tgt_dev->tgt_dev_flags));
TRACE_SN("Deferring cmd %p (sn=%ld, set %d, "
"expected_sn=%ld)", cmd, cmd->sn,
cmd->sn_set, expected_sn);
list_add_tail(&cmd->sn_cmd_list_entry,
&tgt_dev->deferred_cmd_list);
}
spin_unlock_irq(&tgt_dev->sn_lock);
/* !! At this point cmd can be already freed !! */
__scst_dec_on_dev_cmd(dev, cmd_blocking);
goto out_dec_cmd_count;
goto out_put;
} else {
TRACE_SN("Somebody incremented expected_sn %ld, "
"continuing", expected_sn);
@@ -1883,32 +1867,23 @@ exec:
count = 0;
while(1) {
atomic_t *slot = cmd->sn_slot;
int hq = (cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE);
int inc_expected_sn_on_done = cmd->inc_expected_sn_on_done;
int inc_expected_sn = !cmd->inc_expected_sn_on_done &&
cmd->sn_set;
rc = scst_do_send_to_midlev(cmd);
if (rc == SCST_EXEC_NEED_THREAD) {
TRACE_DBG("%s", "scst_do_send_to_midlev() requested "
"thread context, rescheduling");
res = SCST_CMD_STATE_RES_NEED_THREAD;
if (unlikely(hq)) {
TRACE_SN("Rescheduling HQ cmd %p", cmd);
spin_lock_irq(&tgt_dev->sn_lock);
clear_bit(SCST_TGT_DEV_HQ_ACTIVE,
&tgt_dev->tgt_dev_flags);
list_add(&cmd->sn_cmd_list_entry,
&tgt_dev->hq_cmd_list);
spin_unlock_irq(&tgt_dev->sn_lock);
}
scst_dec_on_dev_cmd(cmd);
if (count != 0)
goto out_unplug;
else
goto out_dec_cmd_count;
goto out_put;
}
sBUG_ON(rc != SCST_EXEC_COMPLETED);
/* !! At this point cmd can be already freed !! */
count++;
if ( !inc_expected_sn_on_done && likely(!hq))
if (inc_expected_sn)
scst_inc_expected_sn(tgt_dev, slot);
cmd = scst_check_deferred_commands(tgt_dev);
if (cmd == NULL)
@@ -1921,7 +1896,7 @@ out_unplug:
if (dev->scsi_dev != NULL)
generic_unplug_device(dev->scsi_dev->request_queue);
out_dec_cmd_count:
out_put:
__scst_put();
/* !! At this point sess, dev and tgt_dev can be already freed !! */
@@ -2293,11 +2268,41 @@ static int scst_xmit_response(struct scst_cmd *cmd)
* Check here also in order to avoid unnecessary delays of other
* commands.
*/
if (unlikely(!cmd->sent_to_midlev) && (cmd->tgt_dev != NULL)) {
TRACE_SN("cmd %p was not sent to mid-lev (sn %ld)",
cmd, cmd->sn);
scst_unblock_deferred(cmd->tgt_dev, cmd);
cmd->sent_to_midlev = 1;
if (cmd->tgt_dev != NULL) {
if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE)) {
struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
spin_lock_irq(&tgt_dev->sn_lock);
tgt_dev->hq_cmd_count--;
spin_unlock_irq(&tgt_dev->sn_lock);
EXTRACHECKS_BUG_ON(tgt_dev->hq_cmd_count < 0);
/*
* There is no problem in checking hq_cmd_count in the
* non-locked state. In the worst case we will only have
* unneeded run of the deferred commands.
*/
if (tgt_dev->hq_cmd_count == 0) {
struct scst_cmd *c =
scst_check_deferred_commands(tgt_dev);
if (c != NULL) {
spin_lock_irq(&c->cmd_lists->cmd_list_lock);
TRACE_SN("Adding cmd %p to active cmd list", c);
list_add_tail(&c->cmd_list_entry,
&c->cmd_lists->active_cmd_list);
wake_up(&c->cmd_lists->cmd_list_waitQ);
spin_unlock_irq(&c->cmd_lists->cmd_list_lock);
}
}
}
if (unlikely(!cmd->sent_to_midlev)) {
TRACE_SN("cmd %p was not sent to mid-lev (sn %ld, set %d)",
cmd, cmd->sn, cmd->sn_set);
scst_unblock_deferred(cmd->tgt_dev, cmd);
cmd->sent_to_midlev = 1;
}
}
if (atomic && !cmd->tgtt->xmit_response_atomic) {
@@ -2501,6 +2506,7 @@ static void scst_cmd_set_sn(struct scst_cmd *cmd)
}
cmd->sn_slot = tgt_dev->cur_sn_slot;
cmd->sn = tgt_dev->curr_sn;
tgt_dev->prev_cmd_ordered = 0;
} else {
TRACE(TRACE_MINOR, "%s", "Not enough SN slots");
@@ -2540,10 +2546,9 @@ ordered:
TRACE(TRACE_SCSI|TRACE_SCSI_SERIALIZING, "HQ cmd %p "
"(op %x)", cmd, cmd->cdb[0]);
spin_lock_irqsave(&tgt_dev->sn_lock, flags);
/* Add in the head as required by SAM */
list_add(&cmd->sn_cmd_list_entry, &tgt_dev->hq_cmd_list);
tgt_dev->hq_cmd_count++;
spin_unlock_irqrestore(&tgt_dev->sn_lock, flags);
break;
goto out;
default:
PRINT_ERROR_PR("Unsupported queue type %d, treating it as "
@@ -2559,7 +2564,8 @@ ordered:
tgt_dev->num_free_sn_slots, tgt_dev->prev_cmd_ordered,
tgt_dev->cur_sn_slot-tgt_dev->sn_slots);
cmd->no_sn = 0;
cmd->sn_set = 1;
out:
return;
}
@@ -2652,7 +2658,7 @@ static int __scst_init_cmd(struct scst_cmd *cmd)
"Anonymous" : cmd->sess->initiator_name);
goto out_busy;
}
if (!cmd->no_sn)
if (!cmd->set_sn_on_restart_cmd)
scst_cmd_set_sn(cmd);
} else if (res < 0) {
TRACE_DBG("Finishing cmd %p", cmd);
@@ -3388,8 +3394,9 @@ static int scst_mgmt_cmd_init(struct scst_mgmt_cmd *mcmd)
}
scst_cmd_get(cmd);
spin_unlock_irq(&sess->sess_list_lock);
TRACE(TRACE_MGMT, "Cmd %p for tag %llu (sn %ld) found, "
"aborting it", cmd, mcmd->tag, cmd->sn);
TRACE(TRACE_MGMT, "Cmd %p for tag %llu (sn %ld, set %d, "
"queue_type %x) found, aborting it", cmd, mcmd->tag,
cmd->sn, cmd->sn_set, cmd->queue_type);
mcmd->cmd_to_abort = cmd;
if (mcmd->lun_set && (mcmd->lun != cmd->lun)) {
PRINT_ERROR_PR("ABORT TASK: LUN mismatch: mcmd LUN %Lx, "
@@ -3988,7 +3995,7 @@ static int scst_post_rx_mgmt_cmd(struct scst_session *sess,
if (unlikely(sess->init_phase != SCST_SESS_IPH_READY)) {
switch(sess->init_phase) {
case SCST_SESS_IPH_INITING:
TRACE_DBG("Moving mcmd %p to init deferred mcmd list",
TRACE_DBG("Adding mcmd %p to init deferred mcmd list",
mcmd);
list_add_tail(&mcmd->mgmt_cmd_list_entry,
&sess->init_deferred_mcmd_list);

View File

@@ -184,6 +184,17 @@ static int do_exec(struct vdisk_cmd *vcmd)
TRACE_ENTRY();
switch(cmd->queue_type) {
case SCST_CMD_QUEUE_ORDERED:
TRACE(TRACE_ORDER, "ORDERED cmd_h %d", vcmd->cmd->cmd_h);
break;
case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
TRACE(TRACE_ORDER, "HQ cmd_h %d", vcmd->cmd->cmd_h);
break;
default:
break;
}
memset(reply, 0, sizeof(*reply));
vcmd->reply->cmd_h = vcmd->cmd->cmd_h;
vcmd->reply->subcode = vcmd->cmd->subcode;
@@ -1601,8 +1612,8 @@ restart:
}
if (err < 0) {
PRINT_ERROR_PR("write() returned %Ld from %zd (errno %d)",
(uint64_t)err, length, errno);
PRINT_ERROR_PR("write() returned %Ld from %zd (errno %d, cmd_h "
"%x)", (uint64_t)err, length, errno, vcmd->cmd->cmd_h);
if (err == -EAGAIN)
set_busy(reply);
else {