Fix for long standing protection problem in the initiator driver

git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@474 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2008-07-24 09:04:05 +00:00
parent c006b05884
commit 91b9b7299f
6 changed files with 34 additions and 24 deletions
+1 -1
View File
@@ -1315,7 +1315,7 @@ static char *q2t_find_name(scsi_qla_host_t *ha, int loop_id)
}
/* Find the WWN in the port db given the loop_id */
list_for_each_entry(fcl, &ha->fcports, list) {
list_for_each_entry_rcu(fcl, &ha->fcports, list) {
if (loop_id == (fcl->loop_id & 0xFF)) {
sprintf(wwn_str, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
fcl->port_name[0], fcl->port_name[1],
+5 -5
View File
@@ -240,8 +240,8 @@ out_free:
id_iter += ha->gid_list_info_size;
}
}
get_id_failed:
get_id_failed:
if (size < max_size) {
fc_port_t *fcport;
char * state;
@@ -250,7 +250,7 @@ get_id_failed:
size += scnprintf(buf+size, max_size-size,
"\nfc_ports database\n");
list_for_each_entry(fcport, &ha->fcports, list) {
list_for_each_entry_rcu(fcport, &ha->fcports, list) {
if (size >= max_size)
goto out;
switch (atomic_read(&fcport->state)) {
@@ -1237,7 +1237,7 @@ qla2x00_get_starget_node_name(struct scsi_target *starget)
fc_port_t *fcport;
u64 node_name = 0;
list_for_each_entry(fcport, &ha->fcports, list) {
list_for_each_entry_rcu(fcport, &ha->fcports, list) {
if (fcport->rport &&
starget->id == fcport->rport->scsi_target_id) {
node_name = wwn_to_u64(fcport->node_name);
@@ -1256,7 +1256,7 @@ qla2x00_get_starget_port_name(struct scsi_target *starget)
fc_port_t *fcport;
u64 port_name = 0;
list_for_each_entry(fcport, &ha->fcports, list) {
list_for_each_entry_rcu(fcport, &ha->fcports, list) {
if (fcport->rport &&
starget->id == fcport->rport->scsi_target_id) {
port_name = wwn_to_u64(fcport->port_name);
@@ -1275,7 +1275,7 @@ qla2x00_get_starget_port_id(struct scsi_target *starget)
fc_port_t *fcport;
uint32_t port_id = ~0U;
list_for_each_entry(fcport, &ha->fcports, list) {
list_for_each_entry_rcu(fcport, &ha->fcports, list) {
if (fcport->rport &&
starget->id == fcport->rport->scsi_target_id) {
port_id = fcport->d_id.b.domain << 16 |
+8 -1
View File
@@ -2407,7 +2407,14 @@ typedef struct scsi_qla_host {
struct list_head work_list;
/* Fibre Channel Device List. */
/*
* Fibre Channel Device List.
*
* This list can be accessed from many contexts, including concurrently.
* So, although anything never deleted from this list, it needs the
* corresponding protection anyway. Let's do it by making access to
* it using RCU functions.
*/
struct list_head fcports;
/* RSCN queue. */
+15 -12
View File
@@ -2107,7 +2107,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
/*
* Mark local devices that were present with FCF_DEVICE_LOST for now.
*/
list_for_each_entry(fcport, &pha->fcports, list) {
list_for_each_entry_rcu(fcport, &pha->fcports, list) {
if (fcport->vp_idx != ha->vp_idx)
continue;
@@ -2172,7 +2172,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
/* Check for matching device in port list. */
found = 0;
fcport = NULL;
list_for_each_entry(fcport, &pha->fcports, list) {
list_for_each_entry_rcu(fcport, &pha->fcports, list) {
if (fcport->vp_idx != ha->vp_idx)
continue;
@@ -2201,7 +2201,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
list_add_tail(&new_fcport->vp_fcport,
&ha->vp_fcports);
}
list_add_tail(&new_fcport->list, &pha->fcports);
list_add_tail_rcu(&new_fcport->list, &pha->fcports);
/* Allocate a new replacement fcport. */
fcport = new_fcport;
@@ -2441,7 +2441,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
* Logout all previous fabric devices marked lost, except
* tape devices.
*/
list_for_each_entry(fcport, &pha->fcports, list) {
list_for_each_entry_rcu(fcport, &pha->fcports, list) {
if (fcport->vp_idx !=ha->vp_idx)
continue;
@@ -2475,7 +2475,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
* Scan through our port list and login entries that need to be
* logged in.
*/
list_for_each_entry(fcport, &pha->fcports, list) {
list_for_each_entry_rcu(fcport, &pha->fcports, list) {
if (fcport->vp_idx != ha->vp_idx)
continue;
@@ -2530,10 +2530,13 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
fcport->vp_idx = ha->vp_idx;
list_add_tail(&fcport->vp_fcport,
&ha->vp_fcports);
list_move_tail(&fcport->list,
list_del(&fcport->list);
list_add_tail_rcu(&fcport->list,
&ha->parent->fcports);
} else
list_move_tail(&fcport->list, &ha->fcports);
} else {
list_del(&fcport->list);
list_add_tail_rcu(&fcport->list, &ha->fcports);
}
}
} while (0);
@@ -2716,7 +2719,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
/* Locate matching device in database. */
found = 0;
list_for_each_entry(fcport, &pha->fcports, list) {
list_for_each_entry_rcu(fcport, &pha->fcports, list) {
if (new_fcport->vp_idx != fcport->vp_idx)
continue;
if (memcmp(new_fcport->port_name, fcport->port_name,
@@ -2846,7 +2849,7 @@ qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev)
/* Check for loop ID being already in use. */
found = 0;
fcport = NULL;
list_for_each_entry(fcport, &pha->fcports, list) {
list_for_each_entry_rcu(fcport, &pha->fcports, list) {
if (fcport->loop_id == dev->loop_id && fcport != dev) {
/* ID possibly in use */
found++;
@@ -2960,7 +2963,7 @@ qla2x00_device_resync(scsi_qla_host_t *ha)
rval = QLA_SUCCESS;
list_for_each_entry(fcport, &pha->fcports, list) {
list_for_each_entry_rcu(fcport, &pha->fcports, list) {
if (fcport->vp_idx != ha->vp_idx)
continue;
@@ -3255,7 +3258,7 @@ qla2x00_update_fcports(scsi_qla_host_t *ha)
fc_port_t *fcport;
/* Go with deferred removal of rport references. */
list_for_each_entry(fcport, &ha->fcports, list)
list_for_each_entry_rcu(fcport, &ha->fcports, list)
if (fcport->drport)
qla2x00_rport_del(fcport);
}
+1 -1
View File
@@ -95,7 +95,7 @@ qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha)
fc_port_t *fcport;
scsi_qla_host_t *pha = to_qla_parent(vha);
list_for_each_entry(fcport, &pha->fcports, list) {
list_for_each_entry_rcu(fcport, &pha->fcports, list) {
if (fcport->vp_idx != vha->vp_idx)
continue;
+4 -4
View File
@@ -1007,7 +1007,7 @@ qla2x00_loop_reset(scsi_qla_host_t *ha)
}
if (ha->flags.enable_target_reset) {
list_for_each_entry(fcport, &ha->fcports, list) {
list_for_each_entry_rcu(fcport, &ha->fcports, list) {
if (fcport->port_type != FCT_TARGET)
continue;
@@ -1919,7 +1919,7 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer)
fc_port_t *fcport;
scsi_qla_host_t *pha = to_qla_parent(ha);
list_for_each_entry(fcport, &pha->fcports, list) {
list_for_each_entry_rcu(fcport, &pha->fcports, list) {
if (ha->vp_idx != 0 && ha->vp_idx != fcport->vp_idx)
continue;
/*
@@ -2352,7 +2352,7 @@ qla2x00_do_dpc(void *data)
ha->host_no));
next_loopid = 0;
list_for_each_entry(fcport, &ha->fcports, list) {
list_for_each_entry_rcu(fcport, &ha->fcports, list) {
/*
* If the port is not ONLINE then try to login
* to it if we haven't run out of retries.
@@ -2528,7 +2528,7 @@ qla2x00_timer(scsi_qla_host_t *ha)
* the port it marked DEAD.
*/
t = 0;
list_for_each_entry(fcport, &ha->fcports, list) {
list_for_each_entry_rcu(fcport, &ha->fcports, list) {
if (fcport->port_type != FCT_TARGET)
continue;