diff options
-rw-r--r-- | drivers/scsi/fcoe/fcoe_ctlr.c | 7 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_lport.c | 19 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_rport.c | 49 |
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 | */ |
100 | static struct fc_rport_priv *fc_rport_lookup(const struct fc_lport *lport, | 101 | static 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: | |||
702 | err: | 706 | err: |
703 | mutex_unlock(&rdata->rp_mutex); | 707 | mutex_unlock(&rdata->rp_mutex); |
704 | put: | 708 | put: |
705 | kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy); | 709 | kref_put(&rdata->kref, lport->tt.rport_destroy); |
706 | return; | 710 | return; |
707 | bad: | 711 | bad: |
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); |
852 | out: | 854 | out: |
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 | ||
860 | reject_put: | ||
861 | kref_put(&rdata->kref, lport->tt.rport_destroy); | ||
858 | reject: | 862 | reject: |
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); |
924 | err: | 927 | err: |
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 | ||
929 | static bool | 932 | static 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 | ||
1529 | reject: | 1531 | reject: |
@@ -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 | ||