From 3a2ba412c3b0f87f8a05cf6366e3f9c28c6f96ec Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Wed, 18 May 2011 21:50:01 +0000 Subject: [PATCH] Blocked commands should not pass again through order checks git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@3461 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/include/scst.h | 14 ++++++++++---- scst/src/scst_lib.c | 2 ++ scst/src/scst_targ.c | 25 +++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/scst/include/scst.h b/scst/include/scst.h index 67f4d763b..4a609a08d 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -209,17 +209,23 @@ static inline unsigned int queue_max_hw_sectors(struct request_queue *q) /* Waiting for data from the initiator (until scst_rx_data() called) */ #define SCST_CMD_STATE_DATA_WAIT (SCST_CMD_STATE_LAST_ACTIVE+4) +/* + * Cmd is ready for exec (after check if its device is blocked or should + * be blocked) + */ +#define SCST_CMD_STATE_START_EXEC (SCST_CMD_STATE_LAST_ACTIVE+5) + /* Cmd is being checked if it should be executed locally */ -#define SCST_CMD_STATE_LOCAL_EXEC (SCST_CMD_STATE_LAST_ACTIVE+5) +#define SCST_CMD_STATE_LOCAL_EXEC (SCST_CMD_STATE_LAST_ACTIVE+6) /* Cmd is ready for execution */ -#define SCST_CMD_STATE_REAL_EXEC (SCST_CMD_STATE_LAST_ACTIVE+6) +#define SCST_CMD_STATE_REAL_EXEC (SCST_CMD_STATE_LAST_ACTIVE+7) /* Waiting for CDB's execution finish */ -#define SCST_CMD_STATE_REAL_EXECUTING (SCST_CMD_STATE_LAST_ACTIVE+7) +#define SCST_CMD_STATE_REAL_EXECUTING (SCST_CMD_STATE_LAST_ACTIVE+8) /* Waiting for response's transmission finish */ -#define SCST_CMD_STATE_XMIT_WAIT (SCST_CMD_STATE_LAST_ACTIVE+8) +#define SCST_CMD_STATE_XMIT_WAIT (SCST_CMD_STATE_LAST_ACTIVE+9) /************************************************************* * Can be returned instead of cmd's state by dev handlers' diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 6c0ddae0e..a4b4bb46a 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -1918,6 +1918,7 @@ static int scst_get_cmd_abnormal_done_state(const struct scst_cmd *cmd) case SCST_CMD_STATE_RDY_TO_XFER: case SCST_CMD_STATE_DATA_WAIT: case SCST_CMD_STATE_TGT_PRE_EXEC: + case SCST_CMD_STATE_START_EXEC: case SCST_CMD_STATE_SEND_FOR_EXEC: case SCST_CMD_STATE_LOCAL_EXEC: case SCST_CMD_STATE_REAL_EXEC: @@ -1977,6 +1978,7 @@ int scst_set_cmd_abnormal_done_state(struct scst_cmd *cmd) break; case SCST_CMD_STATE_TGT_PRE_EXEC: case SCST_CMD_STATE_SEND_FOR_EXEC: + case SCST_CMD_STATE_START_EXEC: case SCST_CMD_STATE_LOCAL_EXEC: case SCST_CMD_STATE_REAL_EXEC: case SCST_CMD_STATE_REAL_EXECUTING: diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index dd8fdafbb..777c8adce 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -828,6 +828,7 @@ set_res: case SCST_CMD_STATE_RDY_TO_XFER: case SCST_CMD_STATE_TGT_PRE_EXEC: case SCST_CMD_STATE_SEND_FOR_EXEC: + case SCST_CMD_STATE_START_EXEC: case SCST_CMD_STATE_LOCAL_EXEC: case SCST_CMD_STATE_REAL_EXEC: case SCST_CMD_STATE_PRE_DEV_DONE: @@ -2740,10 +2741,12 @@ static int scst_exec(struct scst_cmd **active_cmd) struct scst_cmd *cmd = *active_cmd; struct scst_cmd *ref_cmd; struct scst_device *dev = cmd->dev; - int res = SCST_CMD_STATE_RES_CONT_NEXT, count; + int res = SCST_CMD_STATE_RES_CONT_NEXT, count = 0; TRACE_ENTRY(); + cmd->state = SCST_CMD_STATE_START_EXEC; + if (unlikely(scst_check_blocked_dev(cmd))) goto out; @@ -2751,7 +2754,6 @@ static int scst_exec(struct scst_cmd **active_cmd) ref_cmd = cmd; __scst_cmd_get(ref_cmd); - count = 0; while (1) { int rc; @@ -2787,12 +2789,15 @@ done: if (cmd == NULL) break; + cmd->state = SCST_CMD_STATE_START_EXEC; + if (unlikely(scst_check_blocked_dev(cmd))) break; __scst_cmd_put(ref_cmd); ref_cmd = cmd; __scst_cmd_get(ref_cmd); + } *active_cmd = cmd; @@ -2808,6 +2813,7 @@ out_put: /* !! At this point sess, dev and tgt_dev can be already freed !! */ out: + EXTRACHECKS_BUG_ON(res == SCST_CMD_STATE_RES_NEED_THREAD); TRACE_EXIT_RES(res); return res; } @@ -3304,6 +3310,7 @@ static int scst_dev_done(struct scst_cmd *cmd) case SCST_CMD_STATE_RDY_TO_XFER: case SCST_CMD_STATE_TGT_PRE_EXEC: case SCST_CMD_STATE_SEND_FOR_EXEC: + case SCST_CMD_STATE_START_EXEC: case SCST_CMD_STATE_LOCAL_EXEC: case SCST_CMD_STATE_REAL_EXEC: case SCST_CMD_STATE_PRE_DEV_DONE: @@ -3356,6 +3363,7 @@ static int scst_dev_done(struct scst_cmd *cmd) switch (state) { case SCST_CMD_STATE_TGT_PRE_EXEC: case SCST_CMD_STATE_SEND_FOR_EXEC: + case SCST_CMD_STATE_START_EXEC: case SCST_CMD_STATE_LOCAL_EXEC: case SCST_CMD_STATE_REAL_EXEC: TRACE_DBG("Atomic context and redirect, " @@ -4123,6 +4131,16 @@ void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic) break; } res = scst_send_for_exec(&cmd); + EXTRACHECKS_BUG_ON(res == SCST_CMD_STATE_RES_NEED_THREAD); + /* + * !! At this point cmd, sess & tgt_dev can already be + * freed !! + */ + break; + + case SCST_CMD_STATE_START_EXEC: + res = scst_exec(&cmd); + EXTRACHECKS_BUG_ON(res == SCST_CMD_STATE_RES_NEED_THREAD); /* * !! At this point cmd, sess & tgt_dev can already be * freed !! @@ -4131,6 +4149,7 @@ void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic) case SCST_CMD_STATE_LOCAL_EXEC: res = scst_local_exec(cmd); + EXTRACHECKS_BUG_ON(res == SCST_CMD_STATE_RES_NEED_THREAD); /* * !! At this point cmd, sess & tgt_dev can already be * freed !! @@ -4139,6 +4158,7 @@ void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic) case SCST_CMD_STATE_REAL_EXEC: res = scst_real_exec(cmd); + EXTRACHECKS_BUG_ON(res == SCST_CMD_STATE_RES_NEED_THREAD); /* * !! At this point cmd, sess & tgt_dev can already be * freed !! @@ -4199,6 +4219,7 @@ void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic) case SCST_CMD_STATE_RDY_TO_XFER: case SCST_CMD_STATE_TGT_PRE_EXEC: case SCST_CMD_STATE_SEND_FOR_EXEC: + case SCST_CMD_STATE_START_EXEC: case SCST_CMD_STATE_LOCAL_EXEC: case SCST_CMD_STATE_REAL_EXEC: case SCST_CMD_STATE_DEV_DONE: