diff options
author | Andreas Herrmann <aherrman@de.ibm.com> | 2005-06-13 07:20:35 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-06-13 22:32:48 -0400 |
commit | 1db2c9c0931a53fe013db55fd2ff58859db31e8d (patch) | |
tree | 1134627ac98d91896dcdb161d5df7ecef60a4de3 /drivers/s390/scsi/zfcp_aux.c | |
parent | 64b29a130901d5b8578e9f602cf2dae56aaff224 (diff) |
[SCSI] zfcp: fix bug during adapter shutdown
Fixes a race between zfcp_fsf_req_dismiss_all and
zfcp_qdio_reqid_check. During adapter shutdown it occurred that a
request was cleaned up twice. First during its normal
completion. Second when dismiss_all was called. The fix is to
serialize access to fsf request list between zfcp_fsf_req_dismiss_all
and zfcp_qdio_reqid_check and delete a fsf request from the list if
its completion is triggered. (Additionally a rwlock was replaced by a
spinlock and fsf_req_cleanup was eliminated.)
Signed-off-by: Andreas Herrmann <aherrman@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/s390/scsi/zfcp_aux.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 6bb4d332b474..c999042dae15 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -520,7 +520,7 @@ zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command, | |||
520 | 520 | ||
521 | out: | 521 | out: |
522 | if (fsf_req != NULL) | 522 | if (fsf_req != NULL) |
523 | zfcp_fsf_req_cleanup(fsf_req); | 523 | zfcp_fsf_req_free(fsf_req); |
524 | 524 | ||
525 | if ((adapter != NULL) && (retval != -ENXIO)) | 525 | if ((adapter != NULL) && (retval != -ENXIO)) |
526 | zfcp_adapter_put(adapter); | 526 | zfcp_adapter_put(adapter); |
@@ -1149,7 +1149,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) | |||
1149 | INIT_LIST_HEAD(&adapter->port_remove_lh); | 1149 | INIT_LIST_HEAD(&adapter->port_remove_lh); |
1150 | 1150 | ||
1151 | /* initialize list of fsf requests */ | 1151 | /* initialize list of fsf requests */ |
1152 | rwlock_init(&adapter->fsf_req_list_lock); | 1152 | spin_lock_init(&adapter->fsf_req_list_lock); |
1153 | INIT_LIST_HEAD(&adapter->fsf_req_list_head); | 1153 | INIT_LIST_HEAD(&adapter->fsf_req_list_head); |
1154 | 1154 | ||
1155 | /* initialize abort lock */ | 1155 | /* initialize abort lock */ |
@@ -1234,9 +1234,9 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter) | |||
1234 | zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); | 1234 | zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); |
1235 | dev_set_drvdata(&adapter->ccw_device->dev, NULL); | 1235 | dev_set_drvdata(&adapter->ccw_device->dev, NULL); |
1236 | /* sanity check: no pending FSF requests */ | 1236 | /* sanity check: no pending FSF requests */ |
1237 | read_lock_irqsave(&adapter->fsf_req_list_lock, flags); | 1237 | spin_lock_irqsave(&adapter->fsf_req_list_lock, flags); |
1238 | retval = !list_empty(&adapter->fsf_req_list_head); | 1238 | retval = !list_empty(&adapter->fsf_req_list_head); |
1239 | read_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); | 1239 | spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); |
1240 | if (retval) { | 1240 | if (retval) { |
1241 | ZFCP_LOG_NORMAL("bug: adapter %s (%p) still in use, " | 1241 | ZFCP_LOG_NORMAL("bug: adapter %s (%p) still in use, " |
1242 | "%i requests outstanding\n", | 1242 | "%i requests outstanding\n", |