diff options
author | Swen Schillig <swen@vnet.ibm.com> | 2009-11-24 18:53:58 +0300 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-12-04 21:02:01 +0300 |
commit | ecf0c7721b104c0ce9c8ca534c911f6310cf92a8 (patch) | |
tree | 639032b36bcbbe905c98c6f0b3b521dc2f0b1806 /drivers/s390/scsi/zfcp_sysfs.c | |
parent | 0a55256d158c18e4821c248a295b7f8f4423660f (diff) | |
download | linux-ecf0c7721b104c0ce9c8ca534c911f6310cf92a8.tar.xz |
[SCSI] zfcp: Replace global config_lock with local list locks
The global config_lock was used to protect the configuration organized
in independent lists. It is not necessary to have a lock on driver
level for this purpose. This patch replaces the global config_lock
with a set of local list locks.
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_sysfs.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_sysfs.c | 48 |
1 files changed, 20 insertions, 28 deletions
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index d31000886ca8..8430b518357e 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -153,15 +153,14 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev, goto out; } - write_lock_irq(&zfcp_data.config_lock); port = zfcp_get_port_by_wwpn(adapter, wwpn); - if (port && (atomic_read(&port->refcount) == 0)) { - zfcp_port_get(port); + if (port && (atomic_read(&port->refcount) == 1)) { atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); + write_lock_irq(&adapter->port_list_lock); list_move(&port->list, &port_remove_lh); + write_unlock_irq(&adapter->port_list_lock); } else port = NULL; - write_unlock_irq(&zfcp_data.config_lock); if (!port) { retval = -ENXIO; @@ -253,35 +252,28 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev, goto out; } - write_lock_irq(&zfcp_data.config_lock); unit = zfcp_get_unit_by_lun(port, fcp_lun); - if (unit) { - write_unlock_irq(&zfcp_data.config_lock); - /* wait for possible timeout during SCSI probe */ - flush_work(&unit->scsi_work); - write_lock_irq(&zfcp_data.config_lock); - - if (atomic_read(&unit->refcount) == 0) { - zfcp_unit_get(unit); - atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, - &unit->status); - list_move(&unit->list, &unit_remove_lh); - } else { - unit = NULL; - } - } - - write_unlock_irq(&zfcp_data.config_lock); - if (!unit) { - retval = -ENXIO; + retval = -EINVAL; goto out; } - zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL); - zfcp_erp_wait(unit->port->adapter); - zfcp_unit_put(unit); - zfcp_unit_dequeue(unit); + /* wait for possible timeout during SCSI probe */ + flush_work(&unit->scsi_work); + + if (atomic_read(&unit->refcount) == 1) { + atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); + + write_lock_irq(&port->unit_list_lock); + list_move(&unit->list, &unit_remove_lh); + write_unlock_irq(&port->unit_list_lock); + + zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL); + zfcp_erp_wait(unit->port->adapter); + zfcp_unit_put(unit); + zfcp_unit_dequeue(unit); + } else + zfcp_unit_put(unit); out: mutex_unlock(&zfcp_data.config_mutex); return retval ? retval : (ssize_t) count; |