Skip to content

Commit

Permalink
[SCSI] zfcp: Ensure all work is cancelled on adapter dequeue
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Swen Schillig authored and James Bottomley committed Mar 12, 2009
1 parent 947a9ac commit 6d1a27f
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 4 deletions.
1 change: 0 additions & 1 deletion drivers/s390/scsi/zfcp_aux.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion drivers/s390/scsi/zfcp_ccw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 6 additions & 2 deletions drivers/s390/scsi/zfcp_fc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) ||
Expand Down

0 comments on commit 6d1a27f

Please sign in to comment.