Re: [PATCH 14/24] libsas: prevent double completion of scmds from eh

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello.

On 17-12-2011 6:34, Dan Williams wrote:

We invoke task->task_done() to free the task in the eh case, but at this
point we are prepared for scsi_eh_flush_done_q() to finish off the scmd.

Introduce sas_end_task() to capture the final response status from the
lldd and free the task.

Also take the opportunity to kill this warning.
drivers/scsi/libsas/sas_scsi_host.c: In function ‘sas_end_task’:
drivers/scsi/libsas/sas_scsi_host.c:102:3: warning: case value ‘2’ not in enumerated type ‘enum exec_status’ [-Wswitch]

Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx>
---
  drivers/scsi/libsas/sas_scsi_host.c |   61 +++++++++++++++++++----------------
  include/scsi/libsas.h               |    5 ++-
  2 files changed, 37 insertions(+), 29 deletions(-)

diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index f32c628..13aee61 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -49,27 +49,12 @@
  #include<linux/scatterlist.h>
  #include<linux/libata.h>

-/* ---------- SCSI Host glue ---------- */
-
-static void sas_scsi_task_done(struct sas_task *task)
+/* record final status and free the task */
+static void sas_end_task(struct scsi_cmnd *sc, struct sas_task *task)
  {
  	struct task_status_struct *ts =&task->task_status;
-	struct scsi_cmnd *sc = task->uldd_task;
  	int hs = 0, stat = 0;
[...]
@@ -124,10 +109,32 @@ static void sas_scsi_task_done(struct sas_task *task)
  			break;
  		}
  	}
-	ASSIGN_SAS_TASK(sc, NULL);
+
  	sc->result = (hs<<  16) | stat;
+	ASSIGN_SAS_TASK(sc, NULL);
  	list_del_init(&task->list);
  	sas_free_task(task);
+}
+
+static void sas_scsi_task_done(struct sas_task *task)
+{
+	struct scsi_cmnd *sc = task->uldd_task;
+
+	if (unlikely(task->task_state_flags&  SAS_TASK_STATE_ABORTED)) {
+		/* Aborted tasks will be completed by the error handler */
+		SAS_DPRINTK("task done but aborted\n");
+		return;
+	}
+
+	if (unlikely(!sc)) {
+		SAS_DPRINTK("task_done called with non existing SCSI cmnd!\n");
+		list_del_init(&task->list);
+		sas_free_task(task);
+		return;
+	}
+
+	ASSIGN_SAS_TASK(sc, NULL);

   Why do it twice -- once here and then in sas_end_task()?

+	sas_end_task(sc, task);
  	sc->scsi_done(sc);
  }

MBR, Sergei
--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux