[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>
This commit is contained in:
Andreas Herrmann
2005-06-13 13:20:35 +02:00
committed by James Bottomley
parent 64b29a1309
commit 1db2c9c093
7 changed files with 46 additions and 81 deletions

View File

@@ -520,7 +520,7 @@ zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
out:
if (fsf_req != NULL)
zfcp_fsf_req_cleanup(fsf_req);
zfcp_fsf_req_free(fsf_req);
if ((adapter != NULL) && (retval != -ENXIO))
zfcp_adapter_put(adapter);
@@ -1149,7 +1149,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device)
INIT_LIST_HEAD(&adapter->port_remove_lh);
/* initialize list of fsf requests */
rwlock_init(&adapter->fsf_req_list_lock);
spin_lock_init(&adapter->fsf_req_list_lock);
INIT_LIST_HEAD(&adapter->fsf_req_list_head);
/* initialize abort lock */
@@ -1234,9 +1234,9 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev);
dev_set_drvdata(&adapter->ccw_device->dev, NULL);
/* sanity check: no pending FSF requests */
read_lock_irqsave(&adapter->fsf_req_list_lock, flags);
spin_lock_irqsave(&adapter->fsf_req_list_lock, flags);
retval = !list_empty(&adapter->fsf_req_list_head);
read_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
if (retval) {
ZFCP_LOG_NORMAL("bug: adapter %s (%p) still in use, "
"%i requests outstanding\n",