]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.arch/s390-10-07-zfcp_refc_work_inflight.patch
Merge branch 'master' of git://git.ipfire.org/ipfire-2.x
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.arch / s390-10-07-zfcp_refc_work_inflight.patch
1 From: Gerald Schaefer <geraldsc@de.ibm.com>
2 Subject: zfcp: fix queue, scheduled work processing.
3 References: bnc#482818,LTC#51963
4
5 Symptom: A nonexisting device might get referenced by a task.
6 Problem: An asynchronous scheduled work might get executed
7 at a time the originating device is already removed.
8 Solution: Secure all devices by proper ref-counting and cancel
9 outstanding work before device-removal.
10
11 Acked-by: John Jolly <jjolly@suse.de>
12 ---
13 drivers/s390/scsi/zfcp_aux.c | 1 +
14 drivers/s390/scsi/zfcp_erp.c | 10 +++++++---
15 2 files changed, 8 insertions(+), 3 deletions(-)
16
17 --- a/drivers/s390/scsi/zfcp_aux.c
18 +++ b/drivers/s390/scsi/zfcp_aux.c
19 @@ -553,6 +553,7 @@ void zfcp_adapter_dequeue(struct zfcp_ad
20
21 cancel_work_sync(&adapter->scan_work);
22 cancel_work_sync(&adapter->stat_work);
23 + cancel_delayed_work_sync(&adapter->nsp.work);
24 zfcp_adapter_scsi_unregister(adapter);
25 sysfs_remove_group(&adapter->ccw_device->dev.kobj,
26 &zfcp_sysfs_adapter_attrs);
27 --- a/drivers/s390/scsi/zfcp_erp.c
28 +++ b/drivers/s390/scsi/zfcp_erp.c
29 @@ -859,7 +859,7 @@ void zfcp_erp_port_strategy_open_lookup(
30 port->erp_action.step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP;
31 if (retval)
32 zfcp_erp_notify(&port->erp_action, ZFCP_ERP_FAILED);
33 -
34 + zfcp_port_put(port);
35 }
36
37 static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
38 @@ -875,7 +875,10 @@ static int zfcp_erp_port_strategy_open_c
39 if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP)
40 return zfcp_erp_open_ptp_port(act);
41 if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) {
42 - queue_work(zfcp_data.work_queue, &port->gid_pn_work);
43 + zfcp_port_get(port);
44 + if (!queue_work(zfcp_data.work_queue,
45 + &port->gid_pn_work))
46 + zfcp_port_put(port);
47 return ZFCP_ERP_CONTINUES;
48 }
49 case ZFCP_ERP_STEP_NAMESERVER_LOOKUP:
50 @@ -1218,7 +1221,8 @@ static void zfcp_erp_schedule_work(struc
51 atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status);
52 INIT_WORK(&p->work, zfcp_erp_scsi_scan);
53 p->unit = unit;
54 - queue_work(zfcp_data.work_queue, &p->work);
55 + if (!queue_work(zfcp_data.work_queue, &p->work))
56 + zfcp_unit_put(unit);
57 }
58
59 static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)