diff options
author | Andreas Herrmann <aherrman@de.ibm.com> | 2005-09-13 15:47:11 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-09-19 14:00:50 -0400 |
commit | 3734d24b2e8d85796de70c13705cfb7cbb1d77df (patch) | |
tree | c89ddff8f636bea1a33bc88873e40dc7d562be46 /drivers/s390/scsi/zfcp_erp.c | |
parent | e0fc15bef0e8c6b5abad6e10cfe3d42e278ae8e8 (diff) |
[SCSI] zfcp: fix race conditions when accessing erp_action lists
o always use locking when changing erp_action lists,
o avoid escalation to ERP_ACTION_REOPEN_PORT_FORCED if erp_action is
still in use for ERP_ACTION_REOPEN_PORT
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_erp.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index cb4f612550ba..376cb0f6cb74 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -886,7 +886,7 @@ static int | |||
886 | zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) | 886 | zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) |
887 | { | 887 | { |
888 | int retval = 0; | 888 | int retval = 0; |
889 | struct zfcp_fsf_req *fsf_req; | 889 | struct zfcp_fsf_req *fsf_req = NULL; |
890 | struct zfcp_adapter *adapter = erp_action->adapter; | 890 | struct zfcp_adapter *adapter = erp_action->adapter; |
891 | 891 | ||
892 | if (erp_action->fsf_req) { | 892 | if (erp_action->fsf_req) { |
@@ -896,7 +896,7 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) | |||
896 | list_for_each_entry(fsf_req, &adapter->fsf_req_list_head, list) | 896 | list_for_each_entry(fsf_req, &adapter->fsf_req_list_head, list) |
897 | if (fsf_req == erp_action->fsf_req) | 897 | if (fsf_req == erp_action->fsf_req) |
898 | break; | 898 | break; |
899 | if (fsf_req == erp_action->fsf_req) { | 899 | if (fsf_req && (fsf_req->erp_action == erp_action)) { |
900 | /* fsf_req still exists */ | 900 | /* fsf_req still exists */ |
901 | debug_text_event(adapter->erp_dbf, 3, "a_ca_req"); | 901 | debug_text_event(adapter->erp_dbf, 3, "a_ca_req"); |
902 | debug_event(adapter->erp_dbf, 3, &fsf_req, | 902 | debug_event(adapter->erp_dbf, 3, &fsf_req, |
@@ -2291,7 +2291,9 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action) | |||
2291 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, | 2291 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, |
2292 | &adapter->status); | 2292 | &adapter->status); |
2293 | ZFCP_LOG_DEBUG("Doing exchange config data\n"); | 2293 | ZFCP_LOG_DEBUG("Doing exchange config data\n"); |
2294 | write_lock(&adapter->erp_lock); | ||
2294 | zfcp_erp_action_to_running(erp_action); | 2295 | zfcp_erp_action_to_running(erp_action); |
2296 | write_unlock(&adapter->erp_lock); | ||
2295 | zfcp_erp_timeout_init(erp_action); | 2297 | zfcp_erp_timeout_init(erp_action); |
2296 | if (zfcp_fsf_exchange_config_data(erp_action)) { | 2298 | if (zfcp_fsf_exchange_config_data(erp_action)) { |
2297 | retval = ZFCP_ERP_FAILED; | 2299 | retval = ZFCP_ERP_FAILED; |
@@ -3194,11 +3196,19 @@ zfcp_erp_action_enqueue(int action, | |||
3194 | /* fall through !!! */ | 3196 | /* fall through !!! */ |
3195 | 3197 | ||
3196 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: | 3198 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
3197 | if (atomic_test_mask | 3199 | if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, |
3198 | (ZFCP_STATUS_COMMON_ERP_INUSE, &port->status) | 3200 | &port->status)) { |
3199 | && port->erp_action.action == | 3201 | if (port->erp_action.action != |
3200 | ZFCP_ERP_ACTION_REOPEN_PORT_FORCED) { | 3202 | ZFCP_ERP_ACTION_REOPEN_PORT_FORCED) { |
3201 | debug_text_event(adapter->erp_dbf, 4, "pf_actenq_drp"); | 3203 | ZFCP_LOG_INFO("dropped erp action %i (port " |
3204 | "0x%016Lx, action in use: %i)\n", | ||
3205 | action, port->wwpn, | ||
3206 | port->erp_action.action); | ||
3207 | debug_text_event(adapter->erp_dbf, 4, | ||
3208 | "pf_actenq_drp"); | ||
3209 | } else | ||
3210 | debug_text_event(adapter->erp_dbf, 4, | ||
3211 | "pf_actenq_drpcp"); | ||
3202 | debug_event(adapter->erp_dbf, 4, &port->wwpn, | 3212 | debug_event(adapter->erp_dbf, 4, &port->wwpn, |
3203 | sizeof (wwn_t)); | 3213 | sizeof (wwn_t)); |
3204 | goto out; | 3214 | goto out; |