[SCSI] zfcp: Ensure all work is cancelled on adapter dequeue
authorSwen Schillig <swen@vnet.ibm.com>
Mon, 2 Mar 2009 12:09:11 +0000 (13:09 +0100)
committerJames Bottomley <James.Bottomley@HansenPartnership.com>
Thu, 12 Mar 2009 17:58:22 +0000 (12:58 -0500)
A scheduled work might still be pending, running while the adapter is
in progress to get dequeued from the system. This can lead to an
invalid pointer dereference (Oops).  Once the adpater is set online
again, ensure the nameserver environment is initialized to the
appropriate values again.

Signed-off-by: Swen Schillig <swen@vnet.ibm.com>
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
drivers/s390/scsi/zfcp_aux.c
drivers/s390/scsi/zfcp_ccw.c
drivers/s390/scsi/zfcp_fc.c

index c4d07be6279ada46f28a548b3928162af63de8a2..616c60ffcf2cda9554dae25de95c6c7cf553ab9e 100644 (file)
@@ -524,7 +524,6 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
                goto sysfs_failed;
 
        atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
-       zfcp_fc_nameserver_init(adapter);
 
        if (!zfcp_adapter_scsi_register(adapter))
                return 0;
index 3aeef289fe7c57cb0328367c89862191d0d8b1d1..1fe1e2eda5121187ecc9d060647c6159afb3cbf1 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Registration and callback for the s390 common I/O layer.
  *
- * Copyright IBM Corporation 2002, 2008
+ * Copyright IBM Corporation 2002, 2009
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -108,6 +108,7 @@ static int zfcp_ccw_set_online(struct ccw_device *ccw_device)
        /* initialize request counter */
        BUG_ON(!zfcp_reqlist_isempty(adapter));
        adapter->req_no = 0;
+       zfcp_fc_nameserver_init(adapter);
 
        zfcp_erp_modify_adapter_status(adapter, "ccsonl1", NULL,
                                       ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
index c22c4786855014270bc30e03f754a370465d041f..aab8123c59664f6b51098080868342b46001c73c 100644 (file)
@@ -98,8 +98,12 @@ static void zfcp_wka_port_offline(struct work_struct *work)
        struct zfcp_wka_port *wka_port =
                        container_of(dw, struct zfcp_wka_port, work);
 
-       wait_event(wka_port->completion_wq,
-                       atomic_read(&wka_port->refcount) == 0);
+       /* Don't wait forvever. If the wka_port is too busy take it offline
+          through a new call later */
+       if (!wait_event_timeout(wka_port->completion_wq,
+                               atomic_read(&wka_port->refcount) == 0,
+                               HZ >> 1))
+               return;
 
        mutex_lock(&wka_port->mutex);
        if ((atomic_read(&wka_port->refcount) != 0) ||