aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorMartin Petermann <martin.petermann@de.ibm.com>2009-05-15 07:18:19 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-05-23 16:44:15 -0400
commita17c5855643afa7838f542cbd0a1ed9a73968cef (patch)
treefec68adb1041443f15dc36cca8ed32ae18170af2 /drivers/s390
parentdceab655d9f7d99881c2033c8ff4e1c7b444e104 (diff)
[SCSI] zfcp: Increase ref counter for port open requests
In rare cases, open port request might timeout, erp calls zfcp_port_put, port gets dequeued. Now, the late returning (or dismissed) fsf-port-open calls the fsf_port_open_handler that tries to reference the port data structure leading to a kernel oops. Signed-off-by: Martin Petermann <martin.petermann@de.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index b550c249389d..6fae2688fede 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -1402,7 +1402,7 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
1402 struct fsf_plogi *plogi; 1402 struct fsf_plogi *plogi;
1403 1403
1404 if (req->status & ZFCP_STATUS_FSFREQ_ERROR) 1404 if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
1405 return; 1405 goto out;
1406 1406
1407 switch (header->fsf_status) { 1407 switch (header->fsf_status) {
1408 case FSF_PORT_ALREADY_OPEN: 1408 case FSF_PORT_ALREADY_OPEN:
@@ -1464,6 +1464,9 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
1464 req->status |= ZFCP_STATUS_FSFREQ_ERROR; 1464 req->status |= ZFCP_STATUS_FSFREQ_ERROR;
1465 break; 1465 break;
1466 } 1466 }
1467
1468out:
1469 zfcp_port_put(port);
1467} 1470}
1468 1471
1469/** 1472/**
@@ -1476,6 +1479,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
1476 struct qdio_buffer_element *sbale; 1479 struct qdio_buffer_element *sbale;
1477 struct zfcp_adapter *adapter = erp_action->adapter; 1480 struct zfcp_adapter *adapter = erp_action->adapter;
1478 struct zfcp_fsf_req *req; 1481 struct zfcp_fsf_req *req;
1482 struct zfcp_port *port = erp_action->port;
1479 int retval = -EIO; 1483 int retval = -EIO;
1480 1484
1481 spin_lock_bh(&adapter->req_q_lock); 1485 spin_lock_bh(&adapter->req_q_lock);
@@ -1496,16 +1500,18 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
1496 sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; 1500 sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
1497 1501
1498 req->handler = zfcp_fsf_open_port_handler; 1502 req->handler = zfcp_fsf_open_port_handler;
1499 req->qtcb->bottom.support.d_id = erp_action->port->d_id; 1503 req->qtcb->bottom.support.d_id = port->d_id;
1500 req->data = erp_action->port; 1504 req->data = port;
1501 req->erp_action = erp_action; 1505 req->erp_action = erp_action;
1502 erp_action->fsf_req = req; 1506 erp_action->fsf_req = req;
1507 zfcp_port_get(port);
1503 1508
1504 zfcp_fsf_start_erp_timer(req); 1509 zfcp_fsf_start_erp_timer(req);
1505 retval = zfcp_fsf_req_send(req); 1510 retval = zfcp_fsf_req_send(req);
1506 if (retval) { 1511 if (retval) {
1507 zfcp_fsf_req_free(req); 1512 zfcp_fsf_req_free(req);
1508 erp_action->fsf_req = NULL; 1513 erp_action->fsf_req = NULL;
1514 zfcp_port_put(port);
1509 } 1515 }
1510out: 1516out:
1511 spin_unlock_bh(&adapter->req_q_lock); 1517 spin_unlock_bh(&adapter->req_q_lock);