diff options
author | Swen Schillig <swen@vnet.ibm.com> | 2010-11-17 08:23:43 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-12-09 10:41:21 -0500 |
commit | 14718e3cd8e9c6937114cebbf3ce5d504328da8c (patch) | |
tree | d9ee10fc825730ce360f50caf53377ebe2872655 /drivers/s390/scsi/zfcp_erp.c | |
parent | d3e1088d68735eb7da12f79a0c3c0d951cbc89f1 (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.c | 9 |
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 | ||