Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4b483802 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull SCSI fixes from James Bottomley:
 "This is a set of seven bug fixes.  Several fcoe fixes for locking
  problems, initiator issues and a VLAN API change, all of which could
  eventually lead to data corruption, one fix for a qla2xxx locking
  problem which could lead to multiple completions of the same request
  (and subsequent data corruption) and a use after free in the ipr
  driver.  Plus one minor MAINTAINERS file update"

(only six bugfixes in this pull, since I had already pulled the fcoe API
fix directly from Robert Love)

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  [SCSI] ipr: Avoid target_destroy accessing memory after it was freed
  [SCSI] qla2xxx: Fix for locking issue between driver ISR and mailbox routines
  MAINTAINERS: Fix fcoe mailing list
  libfc: extend ex_lock to protect all of fc_seq_send
  libfc: Correct check for initiator role
  libfcoe: Fix Conflicting FCFs issue in the fabric
parents 6c355bea a9e94ec3
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -3220,7 +3220,7 @@ F: lib/fault-inject.c


FCOE SUBSYSTEM (libfc, libfcoe, fcoe)
FCOE SUBSYSTEM (libfc, libfcoe, fcoe)
M:	Robert Love <robert.w.love@intel.com>
M:	Robert Love <robert.w.love@intel.com>
L:	devel@open-fcoe.org
L:	fcoe-devel@open-fcoe.org
W:	www.Open-FCoE.org
W:	www.Open-FCoE.org
S:	Supported
S:	Supported
F:	drivers/scsi/libfc/
F:	drivers/scsi/libfc/
+5 −10
Original line number Original line Diff line number Diff line
@@ -1548,9 +1548,6 @@ static struct fcoe_fcf *fcoe_ctlr_select(struct fcoe_ctlr *fip)
{
{
	struct fcoe_fcf *fcf;
	struct fcoe_fcf *fcf;
	struct fcoe_fcf *best = fip->sel_fcf;
	struct fcoe_fcf *best = fip->sel_fcf;
	struct fcoe_fcf *first;

	first = list_first_entry(&fip->fcfs, struct fcoe_fcf, list);


	list_for_each_entry(fcf, &fip->fcfs, list) {
	list_for_each_entry(fcf, &fip->fcfs, list) {
		LIBFCOE_FIP_DBG(fip, "consider FCF fab %16.16llx "
		LIBFCOE_FIP_DBG(fip, "consider FCF fab %16.16llx "
@@ -1568,17 +1565,15 @@ static struct fcoe_fcf *fcoe_ctlr_select(struct fcoe_ctlr *fip)
					"" : "un");
					"" : "un");
			continue;
			continue;
		}
		}
		if (fcf->fabric_name != first->fabric_name ||
		if (!best || fcf->pri < best->pri || best->flogi_sent)
		    fcf->vfid != first->vfid ||
			best = fcf;
		    fcf->fc_map != first->fc_map) {
		if (fcf->fabric_name != best->fabric_name ||
		    fcf->vfid != best->vfid ||
		    fcf->fc_map != best->fc_map) {
			LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, "
			LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, "
					"or FC-MAP\n");
					"or FC-MAP\n");
			return NULL;
			return NULL;
		}
		}
		if (fcf->flogi_sent)
			continue;
		if (!best || fcf->pri < best->pri || best->flogi_sent)
			best = fcf;
	}
	}
	fip->sel_fcf = best;
	fip->sel_fcf = best;
	if (best) {
	if (best) {
+0 −16
Original line number Original line Diff line number Diff line
@@ -8980,19 +8980,6 @@ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
	if (!ioa_cfg->res_entries)
	if (!ioa_cfg->res_entries)
		goto out;
		goto out;


	if (ioa_cfg->sis64) {
		ioa_cfg->target_ids = kzalloc(sizeof(unsigned long) *
					      BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
		ioa_cfg->array_ids = kzalloc(sizeof(unsigned long) *
					     BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
		ioa_cfg->vset_ids = kzalloc(sizeof(unsigned long) *
					    BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);

		if (!ioa_cfg->target_ids || !ioa_cfg->array_ids
			|| !ioa_cfg->vset_ids)
			goto out_free_res_entries;
	}

	for (i = 0; i < ioa_cfg->max_devs_supported; i++) {
	for (i = 0; i < ioa_cfg->max_devs_supported; i++) {
		list_add_tail(&ioa_cfg->res_entries[i].queue, &ioa_cfg->free_res_q);
		list_add_tail(&ioa_cfg->res_entries[i].queue, &ioa_cfg->free_res_q);
		ioa_cfg->res_entries[i].ioa_cfg = ioa_cfg;
		ioa_cfg->res_entries[i].ioa_cfg = ioa_cfg;
@@ -9089,9 +9076,6 @@ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
			    ioa_cfg->vpd_cbs, ioa_cfg->vpd_cbs_dma);
			    ioa_cfg->vpd_cbs, ioa_cfg->vpd_cbs_dma);
out_free_res_entries:
out_free_res_entries:
	kfree(ioa_cfg->res_entries);
	kfree(ioa_cfg->res_entries);
	kfree(ioa_cfg->target_ids);
	kfree(ioa_cfg->array_ids);
	kfree(ioa_cfg->vset_ids);
	goto out;
	goto out;
}
}


+3 −3
Original line number Original line Diff line number Diff line
@@ -1440,9 +1440,9 @@ struct ipr_ioa_cfg {
	/*
	/*
	 * Bitmaps for SIS64 generated target values
	 * Bitmaps for SIS64 generated target values
	 */
	 */
	unsigned long *target_ids;
	unsigned long target_ids[BITS_TO_LONGS(IPR_MAX_SIS64_DEVS)];
	unsigned long *array_ids;
	unsigned long array_ids[BITS_TO_LONGS(IPR_MAX_SIS64_DEVS)];
	unsigned long *vset_ids;
	unsigned long vset_ids[BITS_TO_LONGS(IPR_MAX_SIS64_DEVS)];


	u16 type; /* CCIN of the card */
	u16 type; /* CCIN of the card */


+24 −13
Original line number Original line Diff line number Diff line
@@ -463,13 +463,7 @@ static void fc_exch_delete(struct fc_exch *ep)
	fc_exch_release(ep);	/* drop hold for exch in mp */
	fc_exch_release(ep);	/* drop hold for exch in mp */
}
}


/**
static int fc_seq_send_locked(struct fc_lport *lport, struct fc_seq *sp,
 * fc_seq_send() - Send a frame using existing sequence/exchange pair
 * @lport: The local port that the exchange will be sent on
 * @sp:	   The sequence to be sent
 * @fp:	   The frame to be sent on the exchange
 */
static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp,
		       struct fc_frame *fp)
		       struct fc_frame *fp)
{
{
	struct fc_exch *ep;
	struct fc_exch *ep;
@@ -479,7 +473,7 @@ static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp,
	u8 fh_type = fh->fh_type;
	u8 fh_type = fh->fh_type;


	ep = fc_seq_exch(sp);
	ep = fc_seq_exch(sp);
	WARN_ON((ep->esb_stat & ESB_ST_SEQ_INIT) != ESB_ST_SEQ_INIT);
	WARN_ON(!(ep->esb_stat & ESB_ST_SEQ_INIT));


	f_ctl = ntoh24(fh->fh_f_ctl);
	f_ctl = ntoh24(fh->fh_f_ctl);
	fc_exch_setup_hdr(ep, fp, f_ctl);
	fc_exch_setup_hdr(ep, fp, f_ctl);
@@ -502,17 +496,34 @@ static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp,
	error = lport->tt.frame_send(lport, fp);
	error = lport->tt.frame_send(lport, fp);


	if (fh_type == FC_TYPE_BLS)
	if (fh_type == FC_TYPE_BLS)
		return error;
		goto out;


	/*
	/*
	 * Update the exchange and sequence flags,
	 * Update the exchange and sequence flags,
	 * assuming all frames for the sequence have been sent.
	 * assuming all frames for the sequence have been sent.
	 * We can only be called to send once for each sequence.
	 * We can only be called to send once for each sequence.
	 */
	 */
	spin_lock_bh(&ep->ex_lock);
	ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ;	/* not first seq */
	ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ;	/* not first seq */
	if (f_ctl & FC_FC_SEQ_INIT)
	if (f_ctl & FC_FC_SEQ_INIT)
		ep->esb_stat &= ~ESB_ST_SEQ_INIT;
		ep->esb_stat &= ~ESB_ST_SEQ_INIT;
out:
	return error;
}

/**
 * fc_seq_send() - Send a frame using existing sequence/exchange pair
 * @lport: The local port that the exchange will be sent on
 * @sp:	   The sequence to be sent
 * @fp:	   The frame to be sent on the exchange
 */
static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp,
		       struct fc_frame *fp)
{
	struct fc_exch *ep;
	int error;
	ep = fc_seq_exch(sp);
	spin_lock_bh(&ep->ex_lock);
	error = fc_seq_send_locked(lport, sp, fp);
	spin_unlock_bh(&ep->ex_lock);
	spin_unlock_bh(&ep->ex_lock);
	return error;
	return error;
}
}
@@ -629,7 +640,7 @@ static int fc_exch_abort_locked(struct fc_exch *ep,
	if (fp) {
	if (fp) {
		fc_fill_fc_hdr(fp, FC_RCTL_BA_ABTS, ep->did, ep->sid,
		fc_fill_fc_hdr(fp, FC_RCTL_BA_ABTS, ep->did, ep->sid,
			       FC_TYPE_BLS, FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
			       FC_TYPE_BLS, FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
		error = fc_seq_send(ep->lp, sp, fp);
		error = fc_seq_send_locked(ep->lp, sp, fp);
	} else
	} else
		error = -ENOBUFS;
		error = -ENOBUFS;
	return error;
	return error;
@@ -1132,7 +1143,7 @@ static void fc_seq_send_last(struct fc_seq *sp, struct fc_frame *fp,
	f_ctl = FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT;
	f_ctl = FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT;
	f_ctl |= ep->f_ctl;
	f_ctl |= ep->f_ctl;
	fc_fill_fc_hdr(fp, rctl, ep->did, ep->sid, fh_type, f_ctl, 0);
	fc_fill_fc_hdr(fp, rctl, ep->did, ep->sid, fh_type, f_ctl, 0);
	fc_seq_send(ep->lp, sp, fp);
	fc_seq_send_locked(ep->lp, sp, fp);
}
}


/**
/**
@@ -1307,8 +1318,8 @@ static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp)
		ap->ba_low_seq_cnt = htons(sp->cnt);
		ap->ba_low_seq_cnt = htons(sp->cnt);
	}
	}
	sp = fc_seq_start_next_locked(sp);
	sp = fc_seq_start_next_locked(sp);
	spin_unlock_bh(&ep->ex_lock);
	fc_seq_send_last(sp, fp, FC_RCTL_BA_ACC, FC_TYPE_BLS);
	fc_seq_send_last(sp, fp, FC_RCTL_BA_ACC, FC_TYPE_BLS);
	spin_unlock_bh(&ep->ex_lock);
	fc_frame_free(rx_fp);
	fc_frame_free(rx_fp);
	return;
	return;


Loading