aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndreas Herrmann <aherrman@de.ibm.com>2005-09-13 15:47:11 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-09-19 14:00:50 -0400
commit3734d24b2e8d85796de70c13705cfb7cbb1d77df (patch)
treec89ddff8f636bea1a33bc88873e40dc7d562be46 /drivers
parente0fc15bef0e8c6b5abad6e10cfe3d42e278ae8e8 (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')
-rw-r--r--drivers/s390/scsi/zfcp_erp.c24
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
886zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) 886zfcp_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;