From: Robert Love <robert.w.love@intel.com>
To: james.bottomley@hansenpartnership.com, linux-scsi@vger.kernel.org
Subject: [PATCH 12/24] libfc: check for err when recv and state is incorrect
Date: Fri, 27 Feb 2009 10:55:34 -0800 [thread overview]
Message-ID: <20090227185534.25509.75622.stgit@fritz> (raw)
In-Reply-To: <20090227185430.25509.34309.stgit@fritz>
If we've just created an interface and the an rport is
logging in we may have a request on the wire (say PRLI).
If we destroy the interface, we'll go through each rport
on the disc->rports list and set each rport's state to NONE.
Then the lport will reset the EM. The EM reset will send a
CLOSED event to the prli_resp() handler which will notice
that the state != PRLI. In this case it frees the frame
pointer, decrements the refcount and unlocks the rport.
The problem is that there isn't a frame in this case. It's
just a pointer with an embedded error code. The free causes
an Oops.
This patch moves the error checking to be before the state
checking.
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_lport.c | 50 +++++++++++++++++++++--------------------
drivers/scsi/libfc/fc_rport.c | 30 ++++++++++++-------------
2 files changed, 40 insertions(+), 40 deletions(-)
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 07335ae..c00de22 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1031,17 +1031,17 @@ static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_LPORT("Received a RFT_ID response\n");
+ if (IS_ERR(fp)) {
+ fc_lport_error(lport, fp);
+ goto err;
+ }
+
if (lport->state != LPORT_ST_RFT_ID) {
FC_DBG("Received a RFT_ID response, but in state %s\n",
fc_lport_state(lport));
goto out;
}
- if (IS_ERR(fp)) {
- fc_lport_error(lport, fp);
- goto err;
- }
-
fh = fc_frame_header_get(fp);
ct = fc_frame_payload_get(fp, sizeof(*ct));
@@ -1083,17 +1083,17 @@ static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_LPORT("Received a RPN_ID response\n");
+ if (IS_ERR(fp)) {
+ fc_lport_error(lport, fp);
+ goto err;
+ }
+
if (lport->state != LPORT_ST_RPN_ID) {
FC_DBG("Received a RPN_ID response, but in state %s\n",
fc_lport_state(lport));
goto out;
}
- if (IS_ERR(fp)) {
- fc_lport_error(lport, fp);
- goto err;
- }
-
fh = fc_frame_header_get(fp);
ct = fc_frame_payload_get(fp, sizeof(*ct));
if (fh && ct && fh->fh_type == FC_TYPE_CT &&
@@ -1133,17 +1133,17 @@ static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_LPORT("Received a SCR response\n");
+ if (IS_ERR(fp)) {
+ fc_lport_error(lport, fp);
+ goto err;
+ }
+
if (lport->state != LPORT_ST_SCR) {
FC_DBG("Received a SCR response, but in state %s\n",
fc_lport_state(lport));
goto out;
}
- if (IS_ERR(fp)) {
- fc_lport_error(lport, fp);
- goto err;
- }
-
op = fc_frame_payload_op(fp);
if (op == ELS_LS_ACC)
fc_lport_enter_ready(lport);
@@ -1359,17 +1359,17 @@ static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_LPORT("Received a LOGO response\n");
+ if (IS_ERR(fp)) {
+ fc_lport_error(lport, fp);
+ goto err;
+ }
+
if (lport->state != LPORT_ST_LOGO) {
FC_DBG("Received a LOGO response, but in state %s\n",
fc_lport_state(lport));
goto out;
}
- if (IS_ERR(fp)) {
- fc_lport_error(lport, fp);
- goto err;
- }
-
op = fc_frame_payload_op(fp);
if (op == ELS_LS_ACC)
fc_lport_enter_reset(lport);
@@ -1443,17 +1443,17 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_LPORT("Received a FLOGI response\n");
+ if (IS_ERR(fp)) {
+ fc_lport_error(lport, fp);
+ goto err;
+ }
+
if (lport->state != LPORT_ST_FLOGI) {
FC_DBG("Received a FLOGI response, but in state %s\n",
fc_lport_state(lport));
goto out;
}
- if (IS_ERR(fp)) {
- fc_lport_error(lport, fp);
- goto err;
- }
-
fh = fc_frame_header_get(fp);
did = ntoh24(fh->fh_d_id);
if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) {
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 81b3ca1..4f23a9b 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -505,17 +505,17 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_RPORT("Received a PLOGI response from port (%6x)\n",
rport->port_id);
+ if (IS_ERR(fp)) {
+ fc_rport_error_retry(rport, fp);
+ goto err;
+ }
+
if (rdata->rp_state != RPORT_ST_PLOGI) {
FC_DBG("Received a PLOGI response, but in state %s\n",
fc_rport_state(rport));
goto out;
}
- if (IS_ERR(fp)) {
- fc_rport_error_retry(rport, fp);
- goto err;
- }
-
op = fc_frame_payload_op(fp);
if (op == ELS_LS_ACC &&
(plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) {
@@ -614,17 +614,17 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_RPORT("Received a PRLI response from port (%6x)\n",
rport->port_id);
+ if (IS_ERR(fp)) {
+ fc_rport_error_retry(rport, fp);
+ goto err;
+ }
+
if (rdata->rp_state != RPORT_ST_PRLI) {
FC_DBG("Received a PRLI response, but in state %s\n",
fc_rport_state(rport));
goto out;
}
- if (IS_ERR(fp)) {
- fc_rport_error_retry(rport, fp);
- goto err;
- }
-
op = fc_frame_payload_op(fp);
if (op == ELS_LS_ACC) {
pp = fc_frame_payload_get(fp, sizeof(*pp));
@@ -764,17 +764,17 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_RPORT("Received a RTV response from port (%6x)\n",
rport->port_id);
+ if (IS_ERR(fp)) {
+ fc_rport_error(rport, fp);
+ goto err;
+ }
+
if (rdata->rp_state != RPORT_ST_RTV) {
FC_DBG("Received a RTV response, but in state %s\n",
fc_rport_state(rport));
goto out;
}
- if (IS_ERR(fp)) {
- fc_rport_error(rport, fp);
- goto err;
- }
-
op = fc_frame_payload_op(fp);
if (op == ELS_LS_ACC) {
struct fc_els_rtv_acc *rtv;
next prev parent reply other threads:[~2009-02-27 18:55 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-02-27 18:54 [PATCH 00/24] libfc and fcoe fixes for 2.6.29-rc Robert Love
2009-02-27 18:54 ` [PATCH 01/24] libfc: Pass lport in exch_mgr_reset Robert Love
2009-02-27 18:54 ` [PATCH 02/24] libfc: when rport goes away (re-plogi), clean up exchanges to/from rport Robert Love
2009-02-27 18:54 ` [PATCH 03/24] libfc: handle RRQ exch timeout Robert Love
2009-02-27 18:54 ` [PATCH 04/24] libfc: fixed a soft lockup issue in fc_exch_recv_abts Robert Love
2009-02-27 18:54 ` [PATCH 05/24] libfc, fcoe: fixed locking issues with lport->lp_mutex around lport->link_status Robert Love
2009-02-27 18:55 ` [PATCH 06/24] libfc: rport retry on LS_RJT from certain ELS Robert Love
2009-02-27 18:55 ` [PATCH 07/24] libfc: fixed a read IO data integrity issue when a IO data frame lost Robert Love
2009-02-27 18:55 ` [PATCH 08/24] libfc: exch mgr is freed while lport still retrying sequences Robert Love
2009-02-27 18:55 ` [PATCH 09/24] libfc: Don't violate transport template for rogue port creation Robert Love
2009-02-27 18:55 ` [PATCH 10/24] libfc: correct RPORT_TO_PRIV usage Robert Love
2009-02-27 18:55 ` [PATCH 11/24] libfc: rename rp to rdata in fc_disc_new_target() Robert Love
2009-02-27 18:55 ` Robert Love [this message]
2009-02-27 18:55 ` [PATCH 13/24] libfc: Cleanup libfc_function_template comments Robert Love
2009-02-27 18:55 ` [PATCH 14/24] libfc, fcoe: Fix kerneldoc comments Robert Love
2009-02-27 18:55 ` [PATCH 15/24] libfc, fcoe: Cleanup function formatting and minor typos Robert Love
2009-02-27 18:55 ` [PATCH 16/24] libfc, fcoe: Remove unnecessary cast by removing inline wrapper Robert Love
2009-02-27 18:56 ` [PATCH 17/24] fcoe: Use setup_timer() and mod_timer() Robert Love
2009-02-27 18:56 ` [PATCH 18/24] fcoe: Correct fcoe_transports initialization vs. registration Robert Love
2009-02-27 18:56 ` [PATCH 19/24] libfc: do not change the fh_rx_id of a recevied frame Robert Love
2009-02-27 18:56 ` [PATCH 20/24] fcoe: ETH_P_8021Q is already in if_ether and fcoe is not using it anyway Robert Love
2009-02-27 18:56 ` [PATCH 21/24] fcoe: fix kfree(skb) Robert Love
2009-02-27 18:56 ` [PATCH 22/24] fcoe: Out of order tx frames was causing several check condition SCSI status Robert Love
2009-02-27 18:56 ` [PATCH 23/24] fcoe: fix handling of pending queue, prevent out of order frames (v3) Robert Love
2009-02-27 18:56 ` [PATCH 24/24] fcoe: Change fcoe receive thread nice value from 19 (lowest priority) to -20 Robert Love
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090227185534.25509.75622.stgit@fritz \
--to=robert.w.love@intel.com \
--cc=james.bottomley@hansenpartnership.com \
--cc=linux-scsi@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox