aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/fcoe/fcoe_ctlr.c7
-rw-r--r--drivers/scsi/libfc/fc_lport.c19
-rw-r--r--drivers/scsi/libfc/fc_rport.c49
3 files changed, 38 insertions, 37 deletions
diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c
index 3e83d485f743..ada4bdec9a4c 100644
--- a/drivers/scsi/fcoe/fcoe_ctlr.c
+++ b/drivers/scsi/fcoe/fcoe_ctlr.c
@@ -2496,14 +2496,13 @@ static int fcoe_ctlr_vn_lookup(struct fcoe_ctlr *fip, u32 port_id, u8 *mac)
2496 struct fcoe_rport *frport; 2496 struct fcoe_rport *frport;
2497 int ret = -1; 2497 int ret = -1;
2498 2498
2499 rcu_read_lock();
2500 rdata = lport->tt.rport_lookup(lport, port_id); 2499 rdata = lport->tt.rport_lookup(lport, port_id);
2501 if (rdata) { 2500 if (rdata) {
2502 frport = fcoe_ctlr_rport(rdata); 2501 frport = fcoe_ctlr_rport(rdata);
2503 memcpy(mac, frport->enode_mac, ETH_ALEN); 2502 memcpy(mac, frport->enode_mac, ETH_ALEN);
2504 ret = 0; 2503 ret = 0;
2504 kref_put(&rdata->kref, lport->tt.rport_destroy);
2505 } 2505 }
2506 rcu_read_unlock();
2507 return ret; 2506 return ret;
2508} 2507}
2509 2508
@@ -2585,11 +2584,7 @@ static void fcoe_ctlr_vn_beacon(struct fcoe_ctlr *fip,
2585 fcoe_ctlr_vn_send(fip, FIP_SC_VN_PROBE_REQ, fcoe_all_vn2vn, 0); 2584 fcoe_ctlr_vn_send(fip, FIP_SC_VN_PROBE_REQ, fcoe_all_vn2vn, 0);
2586 return; 2585 return;
2587 } 2586 }
2588 mutex_lock(&lport->disc.disc_mutex);
2589 rdata = lport->tt.rport_lookup(lport, new->ids.port_id); 2587 rdata = lport->tt.rport_lookup(lport, new->ids.port_id);
2590 if (rdata)
2591 kref_get(&rdata->kref);
2592 mutex_unlock(&lport->disc.disc_mutex);
2593 if (rdata) { 2588 if (rdata) {
2594 if (rdata->ids.node_name == new->ids.node_name && 2589 if (rdata->ids.node_name == new->ids.node_name &&
2595 rdata->ids.port_name == new->ids.port_name) { 2590 rdata->ids.port_name == new->ids.port_name) {
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index e01a29863c38..b9b44daff159 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -2090,7 +2090,7 @@ int fc_lport_bsg_request(struct fc_bsg_job *job)
2090 struct fc_rport *rport; 2090 struct fc_rport *rport;
2091 struct fc_rport_priv *rdata; 2091 struct fc_rport_priv *rdata;
2092 int rc = -EINVAL; 2092 int rc = -EINVAL;
2093 u32 did; 2093 u32 did, tov;
2094 2094
2095 job->reply->reply_payload_rcv_len = 0; 2095 job->reply->reply_payload_rcv_len = 0;
2096 if (rsp) 2096 if (rsp)
@@ -2121,15 +2121,20 @@ int fc_lport_bsg_request(struct fc_bsg_job *job)
2121 2121
2122 case FC_BSG_HST_CT: 2122 case FC_BSG_HST_CT:
2123 did = ntoh24(job->request->rqst_data.h_ct.port_id); 2123 did = ntoh24(job->request->rqst_data.h_ct.port_id);
2124 if (did == FC_FID_DIR_SERV) 2124 if (did == FC_FID_DIR_SERV) {
2125 rdata = lport->dns_rdata; 2125 rdata = lport->dns_rdata;
2126 else 2126 if (!rdata)
2127 break;
2128 tov = rdata->e_d_tov;
2129 } else {
2127 rdata = lport->tt.rport_lookup(lport, did); 2130 rdata = lport->tt.rport_lookup(lport, did);
2131 if (!rdata)
2132 break;
2133 tov = rdata->e_d_tov;
2134 kref_put(&rdata->kref, lport->tt.rport_destroy);
2135 }
2128 2136
2129 if (!rdata) 2137 rc = fc_lport_ct_request(job, lport, did, tov);
2130 break;
2131
2132 rc = fc_lport_ct_request(job, lport, did, rdata->e_d_tov);
2133 break; 2138 break;
2134 2139
2135 case FC_BSG_HST_ELS_NOLOGIN: 2140 case FC_BSG_HST_ELS_NOLOGIN:
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 589ff9aedd31..93f596182145 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -95,17 +95,23 @@ static const char *fc_rport_state_names[] = {
95 * @lport: The local port to lookup the remote port on 95 * @lport: The local port to lookup the remote port on
96 * @port_id: The remote port ID to look up 96 * @port_id: The remote port ID to look up
97 * 97 *
98 * The caller must hold either disc_mutex or rcu_read_lock(). 98 * The reference count of the fc_rport_priv structure is
99 * increased by one.
99 */ 100 */
100static struct fc_rport_priv *fc_rport_lookup(const struct fc_lport *lport, 101static struct fc_rport_priv *fc_rport_lookup(const struct fc_lport *lport,
101 u32 port_id) 102 u32 port_id)
102{ 103{
103 struct fc_rport_priv *rdata; 104 struct fc_rport_priv *rdata = NULL, *tmp_rdata;
104 105
105 list_for_each_entry_rcu(rdata, &lport->disc.rports, peers) 106 rcu_read_lock();
106 if (rdata->ids.port_id == port_id) 107 list_for_each_entry_rcu(tmp_rdata, &lport->disc.rports, peers)
107 return rdata; 108 if (tmp_rdata->ids.port_id == port_id &&
108 return NULL; 109 kref_get_unless_zero(&tmp_rdata->kref)) {
110 rdata = tmp_rdata;
111 break;
112 }
113 rcu_read_unlock();
114 return rdata;
109} 115}
110 116
111/** 117/**
@@ -340,7 +346,6 @@ static void fc_rport_work(struct work_struct *work)
340 fc_remote_port_delete(rport); 346 fc_remote_port_delete(rport);
341 } 347 }
342 348
343 mutex_lock(&lport->disc.disc_mutex);
344 mutex_lock(&rdata->rp_mutex); 349 mutex_lock(&rdata->rp_mutex);
345 if (rdata->rp_state == RPORT_ST_DELETE) { 350 if (rdata->rp_state == RPORT_ST_DELETE) {
346 if (port_id == FC_FID_DIR_SERV) { 351 if (port_id == FC_FID_DIR_SERV) {
@@ -370,7 +375,6 @@ static void fc_rport_work(struct work_struct *work)
370 fc_rport_enter_ready(rdata); 375 fc_rport_enter_ready(rdata);
371 mutex_unlock(&rdata->rp_mutex); 376 mutex_unlock(&rdata->rp_mutex);
372 } 377 }
373 mutex_unlock(&lport->disc.disc_mutex);
374 break; 378 break;
375 379
376 default: 380 default:
@@ -702,7 +706,7 @@ out:
702err: 706err:
703 mutex_unlock(&rdata->rp_mutex); 707 mutex_unlock(&rdata->rp_mutex);
704put: 708put:
705 kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy); 709 kref_put(&rdata->kref, lport->tt.rport_destroy);
706 return; 710 return;
707bad: 711bad:
708 FC_RPORT_DBG(rdata, "Bad FLOGI response\n"); 712 FC_RPORT_DBG(rdata, "Bad FLOGI response\n");
@@ -762,8 +766,6 @@ static void fc_rport_recv_flogi_req(struct fc_lport *lport,
762 FC_RPORT_ID_DBG(lport, sid, "Received FLOGI request\n"); 766 FC_RPORT_ID_DBG(lport, sid, "Received FLOGI request\n");
763 767
764 disc = &lport->disc; 768 disc = &lport->disc;
765 mutex_lock(&disc->disc_mutex);
766
767 if (!lport->point_to_multipoint) { 769 if (!lport->point_to_multipoint) {
768 rjt_data.reason = ELS_RJT_UNSUP; 770 rjt_data.reason = ELS_RJT_UNSUP;
769 rjt_data.explan = ELS_EXPL_NONE; 771 rjt_data.explan = ELS_EXPL_NONE;
@@ -808,7 +810,7 @@ static void fc_rport_recv_flogi_req(struct fc_lport *lport,
808 mutex_unlock(&rdata->rp_mutex); 810 mutex_unlock(&rdata->rp_mutex);
809 rjt_data.reason = ELS_RJT_FIP; 811 rjt_data.reason = ELS_RJT_FIP;
810 rjt_data.explan = ELS_EXPL_NOT_NEIGHBOR; 812 rjt_data.explan = ELS_EXPL_NOT_NEIGHBOR;
811 goto reject; 813 goto reject_put;
812 case RPORT_ST_FLOGI: 814 case RPORT_ST_FLOGI:
813 case RPORT_ST_PLOGI_WAIT: 815 case RPORT_ST_PLOGI_WAIT:
814 case RPORT_ST_PLOGI: 816 case RPORT_ST_PLOGI:
@@ -825,13 +827,13 @@ static void fc_rport_recv_flogi_req(struct fc_lport *lport,
825 mutex_unlock(&rdata->rp_mutex); 827 mutex_unlock(&rdata->rp_mutex);
826 rjt_data.reason = ELS_RJT_BUSY; 828 rjt_data.reason = ELS_RJT_BUSY;
827 rjt_data.explan = ELS_EXPL_NONE; 829 rjt_data.explan = ELS_EXPL_NONE;
828 goto reject; 830 goto reject_put;
829 } 831 }
830 if (fc_rport_login_complete(rdata, fp)) { 832 if (fc_rport_login_complete(rdata, fp)) {
831 mutex_unlock(&rdata->rp_mutex); 833 mutex_unlock(&rdata->rp_mutex);
832 rjt_data.reason = ELS_RJT_LOGIC; 834 rjt_data.reason = ELS_RJT_LOGIC;
833 rjt_data.explan = ELS_EXPL_NONE; 835 rjt_data.explan = ELS_EXPL_NONE;
834 goto reject; 836 goto reject_put;
835 } 837 }
836 838
837 fp = fc_frame_alloc(lport, sizeof(*flp)); 839 fp = fc_frame_alloc(lport, sizeof(*flp));
@@ -851,12 +853,13 @@ static void fc_rport_recv_flogi_req(struct fc_lport *lport,
851 fc_rport_state_enter(rdata, RPORT_ST_PLOGI_WAIT); 853 fc_rport_state_enter(rdata, RPORT_ST_PLOGI_WAIT);
852out: 854out:
853 mutex_unlock(&rdata->rp_mutex); 855 mutex_unlock(&rdata->rp_mutex);
854 mutex_unlock(&disc->disc_mutex); 856 kref_put(&rdata->kref, lport->tt.rport_destroy);
855 fc_frame_free(rx_fp); 857 fc_frame_free(rx_fp);
856 return; 858 return;
857 859
860reject_put:
861 kref_put(&rdata->kref, lport->tt.rport_destroy);
858reject: 862reject:
859 mutex_unlock(&disc->disc_mutex);
860 lport->tt.seq_els_rsp_send(rx_fp, ELS_LS_RJT, &rjt_data); 863 lport->tt.seq_els_rsp_send(rx_fp, ELS_LS_RJT, &rjt_data);
861 fc_frame_free(rx_fp); 864 fc_frame_free(rx_fp);
862} 865}
@@ -923,7 +926,7 @@ out:
923 fc_frame_free(fp); 926 fc_frame_free(fp);
924err: 927err:
925 mutex_unlock(&rdata->rp_mutex); 928 mutex_unlock(&rdata->rp_mutex);
926 kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy); 929 kref_put(&rdata->kref, lport->tt.rport_destroy);
927} 930}
928 931
929static bool 932static bool
@@ -1477,14 +1480,11 @@ static void fc_rport_recv_els_req(struct fc_lport *lport, struct fc_frame *fp)
1477 struct fc_rport_priv *rdata; 1480 struct fc_rport_priv *rdata;
1478 struct fc_seq_els_data els_data; 1481 struct fc_seq_els_data els_data;
1479 1482
1480 mutex_lock(&lport->disc.disc_mutex);
1481 rdata = lport->tt.rport_lookup(lport, fc_frame_sid(fp)); 1483 rdata = lport->tt.rport_lookup(lport, fc_frame_sid(fp));
1482 if (!rdata) { 1484 if (!rdata)
1483 mutex_unlock(&lport->disc.disc_mutex);
1484 goto reject; 1485 goto reject;
1485 } 1486
1486 mutex_lock(&rdata->rp_mutex); 1487 mutex_lock(&rdata->rp_mutex);
1487 mutex_unlock(&lport->disc.disc_mutex);
1488 1488
1489 switch (rdata->rp_state) { 1489 switch (rdata->rp_state) {
1490 case RPORT_ST_PRLI: 1490 case RPORT_ST_PRLI:
@@ -1494,6 +1494,7 @@ static void fc_rport_recv_els_req(struct fc_lport *lport, struct fc_frame *fp)
1494 break; 1494 break;
1495 default: 1495 default:
1496 mutex_unlock(&rdata->rp_mutex); 1496 mutex_unlock(&rdata->rp_mutex);
1497 kref_put(&rdata->kref, lport->tt.rport_destroy);
1497 goto reject; 1498 goto reject;
1498 } 1499 }
1499 1500
@@ -1524,6 +1525,7 @@ static void fc_rport_recv_els_req(struct fc_lport *lport, struct fc_frame *fp)
1524 } 1525 }
1525 1526
1526 mutex_unlock(&rdata->rp_mutex); 1527 mutex_unlock(&rdata->rp_mutex);
1528 kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
1527 return; 1529 return;
1528 1530
1529reject: 1531reject:
@@ -1907,7 +1909,6 @@ static void fc_rport_recv_logo_req(struct fc_lport *lport, struct fc_frame *fp)
1907 1909
1908 sid = fc_frame_sid(fp); 1910 sid = fc_frame_sid(fp);
1909 1911
1910 mutex_lock(&lport->disc.disc_mutex);
1911 rdata = lport->tt.rport_lookup(lport, sid); 1912 rdata = lport->tt.rport_lookup(lport, sid);
1912 if (rdata) { 1913 if (rdata) {
1913 mutex_lock(&rdata->rp_mutex); 1914 mutex_lock(&rdata->rp_mutex);
@@ -1916,10 +1917,10 @@ static void fc_rport_recv_logo_req(struct fc_lport *lport, struct fc_frame *fp)
1916 1917
1917 fc_rport_enter_delete(rdata, RPORT_EV_LOGO); 1918 fc_rport_enter_delete(rdata, RPORT_EV_LOGO);
1918 mutex_unlock(&rdata->rp_mutex); 1919 mutex_unlock(&rdata->rp_mutex);
1920 kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
1919 } else 1921 } else
1920 FC_RPORT_ID_DBG(lport, sid, 1922 FC_RPORT_ID_DBG(lport, sid,
1921 "Received LOGO from non-logged-in port\n"); 1923 "Received LOGO from non-logged-in port\n");
1922 mutex_unlock(&lport->disc.disc_mutex);
1923 fc_frame_free(fp); 1924 fc_frame_free(fp);
1924} 1925}
1925 1926