Commit 883a337c authored by Joe Eykholt's avatar Joe Eykholt Committed by James Bottomley

[SCSI] libfc: handle discovery failure more correctly.

Abhijeet Joglekar wrote: "In gpn_ft_resp, if the payload is short,
or unexpected response or out of sequence frame, then we just
return and do nothing. We should either enter fc_disc_done()
with DISC_EV_FAIL which will then restart any queued discovery
requests or call lport module which will reset local port,
or we should call fc_disc_error() so that the gpn_ft is retried.

The situation as is causes discovery to remain pending and never
get restarted, in these rare cases.  We saw this due to a coding
bug in fc_disc before.  The only ways it could happen would be
bugs, packet corruption or an FC fabric problem.

Change it to fail discovery.  The local port will restart
discovery, although it probably should just give up until
the next link flap.
Signed-off-by: default avatarJoe Eykholt <jeykholt@cisco.com>
Signed-off-by: default avatarRobert Love <robert.w.love@intel.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent a1c1e4e7
...@@ -606,6 +606,7 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp, ...@@ -606,6 +606,7 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
if (!cp) { if (!cp) {
FC_DISC_DBG(disc, "GPN_FT response too short, len %d\n", FC_DISC_DBG(disc, "GPN_FT response too short, len %d\n",
fr_len(fp)); fr_len(fp));
event = DISC_EV_FAILED;
} else if (ntohs(cp->ct_cmd) == FC_FS_ACC) { } else if (ntohs(cp->ct_cmd) == FC_FS_ACC) {
/* Accepted, parse the response. */ /* Accepted, parse the response. */
...@@ -619,6 +620,7 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp, ...@@ -619,6 +620,7 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
} else { } else {
FC_DISC_DBG(disc, "GPN_FT unexpected response code " FC_DISC_DBG(disc, "GPN_FT unexpected response code "
"%x\n", ntohs(cp->ct_cmd)); "%x\n", ntohs(cp->ct_cmd));
event = DISC_EV_FAILED;
} }
} else if (fr_sof(fp) == FC_SOF_N3 && seq_cnt == disc->seq_count) { } else if (fr_sof(fp) == FC_SOF_N3 && seq_cnt == disc->seq_count) {
error = fc_disc_gpn_ft_parse(disc, fh + 1, len); error = fc_disc_gpn_ft_parse(disc, fh + 1, len);
...@@ -626,6 +628,7 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp, ...@@ -626,6 +628,7 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DISC_DBG(disc, "GPN_FT unexpected frame - out of sequence? " FC_DISC_DBG(disc, "GPN_FT unexpected frame - out of sequence? "
"seq_cnt %x expected %x sof %x eof %x\n", "seq_cnt %x expected %x sof %x eof %x\n",
seq_cnt, disc->seq_count, fr_sof(fp), fr_eof(fp)); seq_cnt, disc->seq_count, fr_sof(fp), fr_eof(fp));
event = DISC_EV_FAILED;
} }
if (error) if (error)
fc_disc_error(disc, fp); fc_disc_error(disc, fp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment