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

Commit 5b7db7af authored by Krishna Gudipati's avatar Krishna Gudipati Committed by James Bottomley
Browse files

[SCSI] bfa: Implement LUN Masking feature using the SCSI Slave Callouts.



This patch re-implements LUN Masking feature using SCSI Slave Callouts.  With
the new design in the slave_alloc entry point; for each new LUN discovered we
check with our internal LUN Masking config whether to expose or to mask this
particular LUN. We return -ENXIO (No such device or address) from slave_alloc
for the LUNs we don't want to be exposed.  We also notify the SCSI mid-layer
to do a sequential LUN scan rather than REPORT_LUNS based scan if LUN masking
is enabled on our HBA port, since a -ENXIO from any LUN in REPORT_LUNS based
scan translates to a scan abort.  This patch also handles the dynamic lun
masking config change from enable to disable or vice-versa by resetting
sdev_bflags of LUN 0 appropriately.

Signed-off-by: default avatarKrishna Gudipati <kgudipat@brocade.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 8ca2dd87
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -674,6 +674,7 @@ bfad_vport_create(struct bfad_s *bfad, u16 vf_id,

	spin_lock_irqsave(&bfad->bfad_lock, flags);
	bfa_fcs_vport_start(&vport->fcs_vport);
	list_add_tail(&vport->list_entry, &bfad->vport_list);
	spin_unlock_irqrestore(&bfad->bfad_lock, flags);

	return BFA_STATUS_OK;
@@ -1404,6 +1405,7 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
	bfad->ref_count = 0;
	bfad->pport.bfad = bfad;
	INIT_LIST_HEAD(&bfad->pbc_vport_list);
	INIT_LIST_HEAD(&bfad->vport_list);

	/* Setup the debugfs node for this bfad */
	if (bfa_debugfs_enable)
+1 −1
Original line number Diff line number Diff line
@@ -491,7 +491,7 @@ bfad_im_vport_delete(struct fc_vport *fc_vport)

free_scsi_host:
	bfad_scsi_host_free(bfad, im_port);

	list_del(&vport->list_entry);
	kfree(vport);

	return 0;
+24 −3
Original line number Diff line number Diff line
@@ -2394,6 +2394,21 @@ bfad_iocmd_vf_clr_stats(struct bfad_s *bfad, void *cmd)
	return 0;
}

/* Function to reset the LUN SCAN mode */
static void
bfad_iocmd_lunmask_reset_lunscan_mode(struct bfad_s *bfad, int lunmask_cfg)
{
	struct bfad_im_port_s *pport_im = bfad->pport.im_port;
	struct bfad_vport_s *vport = NULL;

	/* Set the scsi device LUN SCAN flags for base port */
	bfad_reset_sdev_bflags(pport_im, lunmask_cfg);

	/* Set the scsi device LUN SCAN flags for the vports */
	list_for_each_entry(vport, &bfad->vport_list, list_entry)
		bfad_reset_sdev_bflags(vport->drv_port.im_port, lunmask_cfg);
}

int
bfad_iocmd_lunmask(struct bfad_s *bfad, void *pcmd, unsigned int v_cmd)
{
@@ -2401,11 +2416,17 @@ bfad_iocmd_lunmask(struct bfad_s *bfad, void *pcmd, unsigned int v_cmd)
	unsigned long	flags;

	spin_lock_irqsave(&bfad->bfad_lock, flags);
	if (v_cmd == IOCMD_FCPIM_LUNMASK_ENABLE)
	if (v_cmd == IOCMD_FCPIM_LUNMASK_ENABLE) {
		iocmd->status = bfa_fcpim_lunmask_update(&bfad->bfa, BFA_TRUE);
	else if (v_cmd == IOCMD_FCPIM_LUNMASK_DISABLE)
		/* Set the LUN Scanning mode to be Sequential scan */
		if (iocmd->status == BFA_STATUS_OK)
			bfad_iocmd_lunmask_reset_lunscan_mode(bfad, BFA_TRUE);
	} else if (v_cmd == IOCMD_FCPIM_LUNMASK_DISABLE) {
		iocmd->status = bfa_fcpim_lunmask_update(&bfad->bfa, BFA_FALSE);
	else if (v_cmd == IOCMD_FCPIM_LUNMASK_CLEAR)
		/* Set the LUN Scanning mode to default REPORT_LUNS scan */
		if (iocmd->status == BFA_STATUS_OK)
			bfad_iocmd_lunmask_reset_lunscan_mode(bfad, BFA_FALSE);
	} else if (v_cmd == IOCMD_FCPIM_LUNMASK_CLEAR)
		iocmd->status = bfa_fcpim_lunmask_clear(&bfad->bfa);
	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
	return 0;
+2 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#include <scsi/scsi_transport_fc.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_bsg_fc.h>
#include <scsi/scsi_devinfo.h>

#include "bfa_modules.h"
#include "bfa_fcs.h"
@@ -227,6 +228,7 @@ struct bfad_s {
	struct list_head	active_aen_q;
	struct bfa_aen_entry_s	aen_list[BFA_AEN_MAX_ENTRY];
	spinlock_t		bfad_aen_spinlock;
	struct list_head	vport_list;
};

/* BFAD state machine events */
+56 −0
Original line number Diff line number Diff line
@@ -917,6 +917,37 @@ bfad_get_itnim(struct bfad_im_port_s *im_port, int id)
	return NULL;
}

/*
 * Function is invoked from the SCSI Host Template slave_alloc() entry point.
 * Has the logic to query the LUN Mask database to check if this LUN needs to
 * be made visible to the SCSI mid-layer or not.
 *
 * Returns BFA_STATUS_OK if this LUN needs to be added to the OS stack.
 * Returns -ENXIO to notify SCSI mid-layer to not add this LUN to the OS stack.
 */
static int
bfad_im_check_if_make_lun_visible(struct scsi_device *sdev,
				  struct fc_rport *rport)
{
	struct bfad_itnim_data_s *itnim_data =
				(struct bfad_itnim_data_s *) rport->dd_data;
	struct bfa_s *bfa = itnim_data->itnim->bfa_itnim->bfa;
	struct bfa_rport_s *bfa_rport = itnim_data->itnim->bfa_itnim->rport;
	struct bfa_lun_mask_s *lun_list = bfa_get_lun_mask_list(bfa);
	int i = 0, ret = -ENXIO;

	for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
		if (lun_list[i].state == BFA_IOIM_LUN_MASK_ACTIVE &&
		    scsilun_to_int(&lun_list[i].lun) == sdev->lun &&
		    lun_list[i].rp_tag == bfa_rport->rport_tag &&
		    lun_list[i].lp_tag == (u8)bfa_rport->rport_info.lp_tag) {
			ret = BFA_STATUS_OK;
			break;
		}
	}
	return ret;
}

/*
 * Scsi_Host template entry slave_alloc
 */
@@ -924,10 +955,33 @@ static int
bfad_im_slave_alloc(struct scsi_device *sdev)
{
	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
	struct bfad_itnim_data_s *itnim_data =
				(struct bfad_itnim_data_s *) rport->dd_data;
	struct bfa_s *bfa = itnim_data->itnim->bfa_itnim->bfa;

	if (!rport || fc_remote_port_chkready(rport))
		return -ENXIO;

	if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_ENABLED) {
		/*
		 * We should not mask LUN 0 - since this will translate
		 * to no LUN / TARGET for SCSI ml resulting no scan.
		 */
		if (sdev->lun == 0) {
			sdev->sdev_bflags |= BLIST_NOREPORTLUN |
					     BLIST_SPARSELUN;
			goto done;
		}

		/*
		 * Query LUN Mask configuration - to expose this LUN
		 * to the SCSI mid-layer or to mask it.
		 */
		if (bfad_im_check_if_make_lun_visible(sdev, rport) !=
							BFA_STATUS_OK)
			return -ENXIO;
	}
done:
	sdev->hostdata = rport->dd_data;

	return 0;
@@ -1037,6 +1091,8 @@ bfad_im_fc_rport_add(struct bfad_im_port_s *im_port, struct bfad_itnim_s *itnim)
	    && (fc_rport->scsi_target_id < MAX_FCP_TARGET))
		itnim->scsi_tgt_id = fc_rport->scsi_target_id;

	itnim->channel = fc_rport->channel;

	return;
}

Loading