Commit 76e72ad1 authored by Hannes Reinecke's avatar Hannes Reinecke Committed by Martin K. Petersen
Browse files

scsi: libfc: sanitize E_D_TOV and R_A_TOV setting



When setting the FCP timeout we need to ensure a lower boundary
for E_D_TOV and R_A_TOV, otherwise we'd be getting spurious I/O
issues due to the fcp timer firing too early.

Signed-off-by: default avatarHannes Reinecke <hare@suse.com>
Acked-by: default avatarJohannes Thumshirn <jth@kernel.org>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent a50cc9ec
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -1137,8 +1137,11 @@ static int fc_fcp_pkt_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp)
static inline unsigned int get_fsp_rec_tov(struct fc_fcp_pkt *fsp)
{
	struct fc_rport_libfc_priv *rpriv = fsp->rport->dd_data;
	unsigned int e_d_tov = FC_DEF_E_D_TOV;

	return msecs_to_jiffies(rpriv->e_d_tov) + HZ;
	if (rpriv && rpriv->e_d_tov > e_d_tov)
		e_d_tov = rpriv->e_d_tov;
	return msecs_to_jiffies(e_d_tov) + HZ;
}

/**
@@ -1693,7 +1696,6 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
	struct fc_seq *seq;
	struct fcp_srr *srr;
	struct fc_frame *fp;
	unsigned int rec_tov;

	rport = fsp->rport;
	rpriv = rport->dd_data;
@@ -1717,10 +1719,9 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
		       rpriv->local_port->port_id, FC_TYPE_FCP,
		       FC_FCTL_REQ, 0);

	rec_tov = get_fsp_rec_tov(fsp);
	seq = lport->tt.exch_seq_send(lport, fp, fc_fcp_srr_resp,
				      fc_fcp_pkt_destroy,
				      fsp, jiffies_to_msecs(rec_tov));
				      fsp, get_fsp_rec_tov(fsp));
	if (!seq)
		goto retry;

+5 −3
Original line number Diff line number Diff line
@@ -1777,7 +1777,7 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
	if ((csp_flags & FC_SP_FT_FPORT) == 0) {
		if (e_d_tov > lport->e_d_tov)
			lport->e_d_tov = e_d_tov;
		lport->r_a_tov = 2 * e_d_tov;
		lport->r_a_tov = 2 * lport->e_d_tov;
		fc_lport_set_port_id(lport, did, fp);
		printk(KERN_INFO "host%d: libfc: "
		       "Port (%6.6x) entered "
@@ -1789,7 +1789,9 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
				   get_unaligned_be64(
					   &flp->fl_wwnn));
	} else {
		if (e_d_tov > lport->e_d_tov)
			lport->e_d_tov = e_d_tov;
		if (r_a_tov > lport->r_a_tov)
			lport->r_a_tov = r_a_tov;
		fc_host_fabric_name(lport->host) =
			get_unaligned_be64(&flp->fl_wwnn);
+4 −2
Original line number Diff line number Diff line
@@ -1296,12 +1296,14 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp,
			tov = ntohl(rtv->rtv_r_a_tov);
			if (tov == 0)
				tov = 1;
			if (tov > rdata->r_a_tov)
				rdata->r_a_tov = tov;
			tov = ntohl(rtv->rtv_e_d_tov);
			if (toq & FC_ELS_RTV_EDRES)
				tov /= 1000000;
			if (tov == 0)
				tov = 1;
			if (tov > rdata->e_d_tov)
				rdata->e_d_tov = tov;
		}
	}