summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSwen Schillig <swen@vnet.ibm.com>2009-03-02 13:09:11 +0100
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-03-12 12:58:22 -0500
commit6d1a27f630f1d30bf85c61ec0436c287d0945fcc (patch)
tree0ad5c2acce91c95ed1a2d12ca58f9f2dac279266
parent947a9aca86eb2a921ed7aa92397cf7f38b896f90 (diff)
[SCSI] zfcp: Ensure all work is cancelled on adapter dequeue
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>
-rw-r--r--drivers/s390/scsi/zfcp_aux.c1
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c3
-rw-r--r--drivers/s390/scsi/zfcp_fc.c8
3 files changed, 8 insertions, 4 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index c4d07be6279..616c60ffcf2 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -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;
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index 3aeef289fe7..1fe1e2eda51 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -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);
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index c22c4786855..aab8123c596 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -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) ||