[SCSI] zfcp: fix queue, scheduled work processing.
authorSwen Schillig <swen@vnet.ibm.com>
Mon, 2 Mar 2009 12:09:10 +0000 (13:09 +0100)
committerJames Bottomley <James.Bottomley@HansenPartnership.com>
Thu, 12 Mar 2009 17:58:22 +0000 (12:58 -0500)
Ensure the refcounting is correct even if we were not able to
schedule a work. In addition we have to make sure no scheduled
work is pending while we're dequeing the adapter from the
systems environment.

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_erp.c

index b2be659..c4d07be 100644 (file)
@@ -554,6 +554,7 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
 
        cancel_work_sync(&adapter->scan_work);
        cancel_work_sync(&adapter->stat_work);
+       cancel_delayed_work_sync(&adapter->nsp.work);
        zfcp_adapter_scsi_unregister(adapter);
        sysfs_remove_group(&adapter->ccw_device->dev.kobj,
                           &zfcp_sysfs_adapter_attrs);
index dee1cc3..631bdb1 100644 (file)
@@ -857,7 +857,7 @@ void zfcp_erp_port_strategy_open_lookup(struct work_struct *work)
        port->erp_action.step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP;
        if (retval)
                zfcp_erp_notify(&port->erp_action, ZFCP_ERP_FAILED);
-
+       zfcp_port_put(port);
 }
 
 static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
@@ -873,7 +873,10 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
                if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP)
                        return zfcp_erp_open_ptp_port(act);
                if (!port->d_id) {
-                       queue_work(zfcp_data.work_queue, &port->gid_pn_work);
+                       zfcp_port_get(port);
+                       if (!queue_work(zfcp_data.work_queue,
+                                       &port->gid_pn_work))
+                               zfcp_port_put(port);
                        return ZFCP_ERP_CONTINUES;
                }
        case ZFCP_ERP_STEP_NAMESERVER_LOOKUP:
@@ -1211,7 +1214,8 @@ static void zfcp_erp_schedule_work(struct zfcp_unit *unit)
        atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status);
        INIT_WORK(&p->work, zfcp_erp_scsi_scan);
        p->unit = unit;
-       queue_work(zfcp_data.work_queue, &p->work);
+       if (!queue_work(zfcp_data.work_queue, &p->work))
+               zfcp_unit_put(unit);
 }
 
 static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)