1 From 251b8184b1bd4e17656d72ba9cffcba733092064 Mon Sep 17 00:00:00 2001
2 From: Robert Love <robert.w.love@intel.com>
3 Date: Mon, 2 Feb 2009 10:13:06 -0800
4 Subject: [PATCH] libfc: check for err when recv and state is incorrect
7 If we've just created an interface and the an rport is
8 logging in we may have a request on the wire (say PRLI).
9 If we destroy the interface, we'll go through each rport
10 on the disc->rports list and set each rport's state to NONE.
11 Then the lport will reset the EM. The EM reset will send a
12 CLOSED event to the prli_resp() handler which will notice
13 that the state != PRLI. In this case it frees the frame
14 pointer, decrements the refcount and unlocks the rport.
16 The problem is that there isn't a frame in this case. It's
17 just a pointer with an embedded error code. The free causes
20 This patch moves the error checking to be before the state
23 Signed-off-by: Robert Love <robert.w.love@intel.com>
24 Signed-off-by: Hannes Reinecke <hare@suse.de>
27 drivers/scsi/libfc/fc_lport.c | 50 +++++++++++++++++++++---------------------
28 drivers/scsi/libfc/fc_rport.c | 30 ++++++++++++-------------
29 2 files changed, 40 insertions(+), 40 deletions(-)
31 --- a/drivers/scsi/libfc/fc_lport.c
32 +++ b/drivers/scsi/libfc/fc_lport.c
33 @@ -1031,17 +1031,17 @@ static void fc_lport_rft_id_resp(struct
35 FC_DEBUG_LPORT("Received a RFT_ID response\n");
38 + fc_lport_error(lport, fp);
42 if (lport->state != LPORT_ST_RFT_ID) {
43 FC_DBG("Received a RFT_ID response, but in state %s\n",
44 fc_lport_state(lport));
49 - fc_lport_error(lport, fp);
53 fh = fc_frame_header_get(fp);
54 ct = fc_frame_payload_get(fp, sizeof(*ct));
56 @@ -1083,17 +1083,17 @@ static void fc_lport_rpn_id_resp(struct
58 FC_DEBUG_LPORT("Received a RPN_ID response\n");
61 + fc_lport_error(lport, fp);
65 if (lport->state != LPORT_ST_RPN_ID) {
66 FC_DBG("Received a RPN_ID response, but in state %s\n",
67 fc_lport_state(lport));
72 - fc_lport_error(lport, fp);
76 fh = fc_frame_header_get(fp);
77 ct = fc_frame_payload_get(fp, sizeof(*ct));
78 if (fh && ct && fh->fh_type == FC_TYPE_CT &&
79 @@ -1133,17 +1133,17 @@ static void fc_lport_scr_resp(struct fc_
81 FC_DEBUG_LPORT("Received a SCR response\n");
84 + fc_lport_error(lport, fp);
88 if (lport->state != LPORT_ST_SCR) {
89 FC_DBG("Received a SCR response, but in state %s\n",
90 fc_lport_state(lport));
95 - fc_lport_error(lport, fp);
99 op = fc_frame_payload_op(fp);
100 if (op == ELS_LS_ACC)
101 fc_lport_enter_ready(lport);
102 @@ -1359,17 +1359,17 @@ static void fc_lport_logo_resp(struct fc
104 FC_DEBUG_LPORT("Received a LOGO response\n");
107 + fc_lport_error(lport, fp);
111 if (lport->state != LPORT_ST_LOGO) {
112 FC_DBG("Received a LOGO response, but in state %s\n",
113 fc_lport_state(lport));
118 - fc_lport_error(lport, fp);
122 op = fc_frame_payload_op(fp);
123 if (op == ELS_LS_ACC)
124 fc_lport_enter_reset(lport);
125 @@ -1443,17 +1443,17 @@ static void fc_lport_flogi_resp(struct f
127 FC_DEBUG_LPORT("Received a FLOGI response\n");
130 + fc_lport_error(lport, fp);
134 if (lport->state != LPORT_ST_FLOGI) {
135 FC_DBG("Received a FLOGI response, but in state %s\n",
136 fc_lport_state(lport));
141 - fc_lport_error(lport, fp);
145 fh = fc_frame_header_get(fp);
146 did = ntoh24(fh->fh_d_id);
147 if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) {
148 --- a/drivers/scsi/libfc/fc_rport.c
149 +++ b/drivers/scsi/libfc/fc_rport.c
150 @@ -505,17 +505,17 @@ static void fc_rport_plogi_resp(struct f
151 FC_DEBUG_RPORT("Received a PLOGI response from port (%6x)\n",
155 + fc_rport_error_retry(rport, fp);
159 if (rdata->rp_state != RPORT_ST_PLOGI) {
160 FC_DBG("Received a PLOGI response, but in state %s\n",
161 fc_rport_state(rport));
166 - fc_rport_error_retry(rport, fp);
170 op = fc_frame_payload_op(fp);
171 if (op == ELS_LS_ACC &&
172 (plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) {
173 @@ -614,17 +614,17 @@ static void fc_rport_prli_resp(struct fc
174 FC_DEBUG_RPORT("Received a PRLI response from port (%6x)\n",
178 + fc_rport_error_retry(rport, fp);
182 if (rdata->rp_state != RPORT_ST_PRLI) {
183 FC_DBG("Received a PRLI response, but in state %s\n",
184 fc_rport_state(rport));
189 - fc_rport_error_retry(rport, fp);
193 op = fc_frame_payload_op(fp);
194 if (op == ELS_LS_ACC) {
195 pp = fc_frame_payload_get(fp, sizeof(*pp));
196 @@ -764,17 +764,17 @@ static void fc_rport_rtv_resp(struct fc_
197 FC_DEBUG_RPORT("Received a RTV response from port (%6x)\n",
201 + fc_rport_error(rport, fp);
205 if (rdata->rp_state != RPORT_ST_RTV) {
206 FC_DBG("Received a RTV response, but in state %s\n",
207 fc_rport_state(rport));
212 - fc_rport_error(rport, fp);
216 op = fc_frame_payload_op(fp);
217 if (op == ELS_LS_ACC) {
218 struct fc_els_rtv_acc *rtv;