aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_erp.c
diff options
context:
space:
mode:
authorSwen Schillig <swen@vnet.ibm.com>2010-11-17 08:23:43 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-12-09 10:41:21 -0500
commit14718e3cd8e9c6937114cebbf3ce5d504328da8c (patch)
treed9ee10fc825730ce360f50caf53377ebe2872655 /drivers/s390/scsi/zfcp_erp.c
parentd3e1088d68735eb7da12f79a0c3c0d951cbc89f1 (diff)
[SCSI] zfcp: Prevent usage w/o holding a reference
The ERP got values assigned for which no reference was taken. This can lead to an unpredictable race condition. Fix this by only assigning the values which are required and for which a reference was pulled or is held implicitly. 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@suse.de>
Diffstat (limited to 'drivers/s390/scsi/zfcp_erp.c')
-rw-r--r--drivers/s390/scsi/zfcp_erp.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 63422c13c7da..0bcd5806bd9a 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -190,6 +190,9 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
190 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, 190 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
191 &zfcp_sdev->status); 191 &zfcp_sdev->status);
192 erp_action = &zfcp_sdev->erp_action; 192 erp_action = &zfcp_sdev->erp_action;
193 memset(erp_action, 0, sizeof(struct zfcp_erp_action));
194 erp_action->port = port;
195 erp_action->sdev = sdev;
193 if (!(atomic_read(&zfcp_sdev->status) & 196 if (!(atomic_read(&zfcp_sdev->status) &
194 ZFCP_STATUS_COMMON_RUNNING)) 197 ZFCP_STATUS_COMMON_RUNNING))
195 act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; 198 act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
@@ -202,6 +205,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
202 zfcp_erp_action_dismiss_port(port); 205 zfcp_erp_action_dismiss_port(port);
203 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); 206 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
204 erp_action = &port->erp_action; 207 erp_action = &port->erp_action;
208 memset(erp_action, 0, sizeof(struct zfcp_erp_action));
209 erp_action->port = port;
205 if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING)) 210 if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING))
206 act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; 211 act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
207 break; 212 break;
@@ -211,6 +216,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
211 zfcp_erp_action_dismiss_adapter(adapter); 216 zfcp_erp_action_dismiss_adapter(adapter);
212 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status); 217 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status);
213 erp_action = &adapter->erp_action; 218 erp_action = &adapter->erp_action;
219 memset(erp_action, 0, sizeof(struct zfcp_erp_action));
214 if (!(atomic_read(&adapter->status) & 220 if (!(atomic_read(&adapter->status) &
215 ZFCP_STATUS_COMMON_RUNNING)) 221 ZFCP_STATUS_COMMON_RUNNING))
216 act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; 222 act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
@@ -220,10 +226,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
220 return NULL; 226 return NULL;
221 } 227 }
222 228
223 memset(erp_action, 0, sizeof(struct zfcp_erp_action));
224 erp_action->adapter = adapter; 229 erp_action->adapter = adapter;
225 erp_action->port = port;
226 erp_action->sdev = sdev;
227 erp_action->action = need; 230 erp_action->action = need;
228 erp_action->status = act_status; 231 erp_action->status = act_status;
229 232