Patch from Smadar Gonen <smadar.gn@gmail.com> with minor changes fixing race in task...
authorvlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Tue, 15 Dec 2009 18:32:13 +0000 (18:32 +0000)
committervlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Tue, 15 Dec 2009 18:32:13 +0000 (18:32 +0000)
git-svn-id: https://scst.svn.sourceforge.net/svnroot/scst/trunk@1392 d57e44dd-8a1f-0410-8b47-8ef2f437770f

scst/include/scst.h
scst/src/scst_targ.c

index ac84fbd..6c41af0 100644 (file)
@@ -436,14 +436,11 @@ enum scst_exec_context {
 /* Set if the cmd is aborted by other initiator */
 #define SCST_CMD_ABORTED_OTHER         1
 
-/* Set if the cmd is aborted and counted in cmd_done_wait_count */
-#define SCST_CMD_DONE_COUNTED          2
-
 /* Set if no response should be sent to the target about this cmd */
-#define SCST_CMD_NO_RESP               3
+#define SCST_CMD_NO_RESP               2
 
 /* Set if the cmd is dead and can be destroyed at any time */
-#define SCST_CMD_CAN_BE_DESTROYED      4
+#define SCST_CMD_CAN_BE_DESTROYED      3
 
 /*************************************************************
  ** Tgt_dev's async. flags (tgt_dev_flags)
@@ -1634,6 +1631,9 @@ struct scst_mgmt_cmd_stub {
 
        /* List entry in cmd->mgmt_cmd_list */
        struct list_head cmd_mgmt_cmd_list_entry;
+
+       /* set if the cmd was counted in  mcmd->cmd_done_wait_count */
+       unsigned int done_counted:1;
 };
 
 struct scst_mgmt_cmd {
index d7a3166..28dcf67 100644 (file)
@@ -3841,13 +3841,14 @@ void scst_done_cmd_mgmt(struct scst_cmd *cmd)
 
        spin_lock_irqsave(&scst_mcmd_lock, flags);
 
-       if (!test_bit(SCST_CMD_DONE_COUNTED, &cmd->cmd_flags))
-               goto out_unlock;
-
        list_for_each_entry(mstb, &cmd->mgmt_cmd_list,
                        cmd_mgmt_cmd_list_entry) {
-               struct scst_mgmt_cmd *mcmd = mstb->mcmd;
+               struct scst_mgmt_cmd *mcmd;
 
+               if (!mstb->done_counted)
+                       continue;
+
+               mcmd = mstb->mcmd;
                TRACE_MGMT_DBG("mcmd %p, mcmd->cmd_done_wait_count %d",
                        mcmd, mcmd->cmd_done_wait_count);
 
@@ -3870,7 +3871,6 @@ void scst_done_cmd_mgmt(struct scst_cmd *cmd)
                }
        }
 
-out_unlock:
        spin_unlock_irqrestore(&scst_mcmd_lock, flags);
 
        if (wake)
@@ -4089,6 +4089,8 @@ void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd,
                                "stub failed (mcmd %p, cmd %p)", mcmd, cmd);
                        goto unlock;
                }
+               memset(mstb, 0, sizeof(mstb));
+
                mstb->mcmd = mcmd;
 
                /*
@@ -4122,7 +4124,7 @@ void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd,
                        TRACE_MGMT_DBG("cmd %p (tag %llu) is being executed "
                                "and not done yet", cmd,
                                (long long unsigned int)cmd->tag);
-                       set_bit(SCST_CMD_DONE_COUNTED, &cmd->cmd_flags);
+                       mstb->done_counted = 1;
                        mcmd->cmd_done_wait_count++;
                }
        }