Re: [PATCHv3] scsi: disable automatic target scan

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2016-03-17 at 08:39 +0100, Hannes Reinecke wrote:
> On larger installations it is useful to disable automatic LUN
> scanning, and only add the required LUNs via udev rules.
> This can speed up bootup dramatically.
> 
> This patch introduces a new scan module parameter value 'manual',
> which works like 'none', but can be overriden by setting the 'rescan'
> value from scsi_scan_target to 'SCSI_SCAN_MANUAL'.
> And it updates all relevant callers to set the 'rescan' value
> to 'SCSI_SCAN_MANUAL' if invoked via the 'scan' option in sysfs.
> 
> Signed-off-by: Hannes Reinecke <hare@xxxxxxx>
> ---
>  drivers/infiniband/ulp/srp/ib_srp.c |  2 +-
>  drivers/message/fusion/mptspi.c     |  2 +-
>  drivers/s390/scsi/zfcp_unit.c       |  3 ++-
>  drivers/scsi/scsi_priv.h            |  2 +-
>  drivers/scsi/scsi_proc.c            |  3 ++-
>  drivers/scsi/scsi_scan.c            | 44 +++++++++++++++++++++++++------------
>  drivers/scsi/scsi_sysfs.c           |  3 ++-
>  drivers/scsi/scsi_transport_fc.c    |  6 +++--
>  drivers/scsi/scsi_transport_iscsi.c |  5 ++++-
>  drivers/scsi/scsi_transport_sas.c   |  7 +++---
>  drivers/scsi/snic/snic_disc.c       |  2 +-
>  include/scsi/scsi_device.h          |  9 +++++++-
>  12 files changed, 60 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
> index 03022f6..1f97381 100644
> --- a/drivers/infiniband/ulp/srp/ib_srp.c
> +++ b/drivers/infiniband/ulp/srp/ib_srp.c
> @@ -2851,7 +2851,7 @@ static int srp_add_target(struct srp_host *host, struct srp_target_port *target)
>  	spin_unlock(&host->target_lock);
>  
>  	scsi_scan_target(&target->scsi_host->shost_gendev,
> -			 0, target->scsi_id, SCAN_WILD_CARD, 0);
> +			 0, target->scsi_id, SCAN_WILD_CARD, SCSI_SCAN_INITIAL);
>  
>  	if (srp_connected_ch(target) < target->ch_count ||
>  	    target->qp_in_error) {
> diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
> index 613231c..031e088 100644
> --- a/drivers/message/fusion/mptspi.c
> +++ b/drivers/message/fusion/mptspi.c
> @@ -1150,7 +1150,7 @@ static void mpt_work_wrapper(struct work_struct *work)
>  	}
>  	shost_printk(KERN_INFO, shost, MYIOC_s_FMT
>  	    "Integrated RAID detects new device %d\n", ioc->name, disk);
> -	scsi_scan_target(&ioc->sh->shost_gendev, 1, disk, 0, 1);
> +	scsi_scan_target(&ioc->sh->shost_gendev, 1, disk, 0, SCSI_SCAN_RESCAN);
>  }
>  
> 
> diff --git a/drivers/s390/scsi/zfcp_unit.c b/drivers/s390/scsi/zfcp_unit.c
> index 157d3d2..08bba7c 100644
> --- a/drivers/s390/scsi/zfcp_unit.c
> +++ b/drivers/s390/scsi/zfcp_unit.c
> @@ -26,7 +26,8 @@ void zfcp_unit_scsi_scan(struct zfcp_unit *unit)
>  	lun = scsilun_to_int((struct scsi_lun *) &unit->fcp_lun);
>  
>  	if (rport && rport->port_state == FC_PORTSTATE_ONLINE)
> -		scsi_scan_target(&rport->dev, 0, rport->scsi_target_id, lun, 1);
> +		scsi_scan_target(&rport->dev, 0, rport->scsi_target_id, lun,
> +				 SCSI_SCAN_RESCAN);
>  }
>  
>  static void zfcp_unit_scsi_scan_work(struct work_struct *work)
> diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
> index 27b4d0a..57a4b99 100644
> --- a/drivers/scsi/scsi_priv.h
> +++ b/drivers/scsi/scsi_priv.h
> @@ -116,7 +116,7 @@ extern void scsi_exit_procfs(void);
>  extern char scsi_scan_type[];
>  extern int scsi_complete_async_scans(void);
>  extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int,
> -				   unsigned int, u64, int);
> +				   unsigned int, u64, enum scsi_scan_mode);
>  extern void scsi_forget_host(struct Scsi_Host *);
>  extern void scsi_rescan_device(struct device *);
>  
> diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c
> index 251598e..7a74b82 100644
> --- a/drivers/scsi/scsi_proc.c
> +++ b/drivers/scsi/scsi_proc.c
> @@ -251,7 +251,8 @@ static int scsi_add_single_device(uint host, uint channel, uint id, uint lun)
>  	if (shost->transportt->user_scan)
>  		error = shost->transportt->user_scan(shost, channel, id, lun);
>  	else
> -		error = scsi_scan_host_selected(shost, channel, id, lun, 1);
> +		error = scsi_scan_host_selected(shost, channel, id, lun,
> +						SCSI_SCAN_MANUAL);
>  	scsi_host_put(shost);
>  	return error;
>  }
> diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
> index 97074c9..6c8ad36 100644
> --- a/drivers/scsi/scsi_scan.c
> +++ b/drivers/scsi/scsi_scan.c
> @@ -96,10 +96,13 @@ MODULE_PARM_DESC(max_luns,
>  #define SCSI_SCAN_TYPE_DEFAULT "sync"
>  #endif
>  
> -char scsi_scan_type[6] = SCSI_SCAN_TYPE_DEFAULT;
> +char scsi_scan_type[7] = SCSI_SCAN_TYPE_DEFAULT;
>  
> -module_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type), S_IRUGO);
> -MODULE_PARM_DESC(scan, "sync, async or none");
> +module_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type),
> +		    S_IRUGO|S_IWUSR);
> +MODULE_PARM_DESC(scan, "sync, async, manual, or none. "
> +		 "Setting to 'manual' disables automatic scanning, but allows "
> +		 "for manual device scan via the 'scan' sysfs attribute.");
>  
>  static unsigned int scsi_inq_timeout = SCSI_TIMEOUT/HZ + 18;
>  
> @@ -1040,7 +1043,8 @@ static unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq,
>   * @lun:	LUN of target device
>   * @bflagsp:	store bflags here if not NULL
>   * @sdevp:	probe the LUN corresponding to this scsi_device
> - * @rescan:     if nonzero skip some code only needed on first scan
> + * @rescan:     if not equal to SCSI_SCAN_INITIAL skip some code only
> + *              needed on first scan
>   * @hostdata:	passed to scsi_alloc_sdev()
>   *
>   * Description:
> @@ -1055,7 +1059,8 @@ static unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq,
>   **/
>  static int scsi_probe_and_add_lun(struct scsi_target *starget,
>  				  u64 lun, int *bflagsp,
> -				  struct scsi_device **sdevp, int rescan,
> +				  struct scsi_device **sdevp,
> +				  enum scsi_scan_mode rescan,
>  				  void *hostdata)
>  {
>  	struct scsi_device *sdev;
> @@ -1069,7 +1074,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
>  	 */
>  	sdev = scsi_device_lookup_by_target(starget, lun);
>  	if (sdev) {
> -		if (rescan || !scsi_device_created(sdev)) {
> +		if (rescan != SCSI_SCAN_INITIAL || !scsi_device_created(sdev)) {
>  			SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev,
>  				"scsi scan: device exists on %s\n",
>  				dev_name(&sdev->sdev_gendev)));
> @@ -1205,7 +1210,8 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
>   *     Modifies sdevscan->lun.
>   **/
>  static void scsi_sequential_lun_scan(struct scsi_target *starget,
> -				     int bflags, int scsi_level, int rescan)
> +				     int bflags, int scsi_level,
> +				     enum scsi_scan_mode rescan)
>  {
>  	uint max_dev_lun;
>  	u64 sparse_lun, lun;
> @@ -1300,7 +1306,7 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget,
>   *     1: could not scan with REPORT LUN
>   **/
>  static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
> -				int rescan)
> +				enum scsi_scan_mode rescan)
>  {
>  	char devname[64];
>  	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
> @@ -1546,7 +1552,7 @@ void scsi_rescan_device(struct device *dev)
>  EXPORT_SYMBOL(scsi_rescan_device);
>  
>  static void __scsi_scan_target(struct device *parent, unsigned int channel,
> -		unsigned int id, u64 lun, int rescan)
> +		unsigned int id, u64 lun, enum scsi_scan_mode rescan)
>  {
>  	struct Scsi_Host *shost = dev_to_shost(parent);
>  	int bflags = 0;
> @@ -1604,7 +1610,10 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
>   * @channel:	channel to scan
>   * @id:		target id to scan
>   * @lun:	Specific LUN to scan or SCAN_WILD_CARD
> - * @rescan:	passed to LUN scanning routines
> + * @rescan:	passed to LUN scanning routines; SCSI_SCAN_INITIAL for
> + *              no rescan, SCSI_SCAN_RESCAN to rescan existing LUNs,
> + *              and SCSI_SCAN_MANUAL to force scanning even if
> + *              'scan=manual' is set.
>   *
>   * Description:
>   *     Scan the target id on @parent, @channel, and @id. Scan at least LUN 0,
> @@ -1614,13 +1623,17 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
>   *     sequential scan of LUNs on the target id.
>   **/
>  void scsi_scan_target(struct device *parent, unsigned int channel,
> -		      unsigned int id, u64 lun, int rescan)
> +		      unsigned int id, u64 lun, enum scsi_scan_mode rescan)
>  {
>  	struct Scsi_Host *shost = dev_to_shost(parent);
>  
>  	if (strncmp(scsi_scan_type, "none", 4) == 0)
>  		return;
>  
> +	if (rescan != SCSI_SCAN_MANUAL &&
> +	    strncmp(scsi_scan_type, "manual", 6) == 0)
> +		return;
> +
>  	mutex_lock(&shost->scan_mutex);
>  	if (!shost->async_scan)
>  		scsi_complete_async_scans();
> @@ -1634,7 +1647,8 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
>  EXPORT_SYMBOL(scsi_scan_target);
>  
>  static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
> -			      unsigned int id, u64 lun, int rescan)
> +			      unsigned int id, u64 lun,
> +			      enum scsi_scan_mode rescan)
>  {
>  	uint order_id;
>  
> @@ -1665,7 +1679,8 @@ static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
>  }
>  
>  int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
> -			    unsigned int id, u64 lun, int rescan)
> +			    unsigned int id, u64 lun,
> +			    enum scsi_scan_mode rescan)
>  {
>  	SCSI_LOG_SCAN_BUS(3, shost_printk (KERN_INFO, shost,
>  		"%s: <%u:%u:%llu>\n",
> @@ -1844,7 +1859,8 @@ void scsi_scan_host(struct Scsi_Host *shost)
>  {
>  	struct async_scan_data *data;
>  
> -	if (strncmp(scsi_scan_type, "none", 4) == 0)
> +	if (strncmp(scsi_scan_type, "none", 4) == 0 ||
> +	    strncmp(scsi_scan_type, "manual", 6) == 0)
>  		return;
>  	if (scsi_autopm_get_host(shost) < 0)
>  		return;
> diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
> index 92ffd24..3b2045f 100644
> --- a/drivers/scsi/scsi_sysfs.c
> +++ b/drivers/scsi/scsi_sysfs.c
> @@ -143,7 +143,8 @@ static int scsi_scan(struct Scsi_Host *shost, const char *str)
>  	if (shost->transportt->user_scan)
>  		res = shost->transportt->user_scan(shost, channel, id, lun);
>  	else
> -		res = scsi_scan_host_selected(shost, channel, id, lun, 1);
> +		res = scsi_scan_host_selected(shost, channel, id, lun,
> +					      SCSI_SCAN_MANUAL);
>  	return res;
>  }
>  
> diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
> index 8a88226..bf28c68 100644
> --- a/drivers/scsi/scsi_transport_fc.c
> +++ b/drivers/scsi/scsi_transport_fc.c
> @@ -2110,7 +2110,8 @@ fc_user_scan_tgt(struct Scsi_Host *shost, uint channel, uint id, u64 lun)
>  		if ((channel == rport->channel) &&
>  		    (id == rport->scsi_target_id)) {
>  			spin_unlock_irqrestore(shost->host_lock, flags);
> -			scsi_scan_target(&rport->dev, channel, id, lun, 1);
> +			scsi_scan_target(&rport->dev, channel, id, lun,
> +					 SCSI_SCAN_MANUAL);
>  			return;
>  		}
>  	}
> @@ -3277,7 +3278,8 @@ fc_scsi_scan_rport(struct work_struct *work)
>  	    (rport->roles & FC_PORT_ROLE_FCP_TARGET) &&
>  	    !(i->f->disable_target_scan)) {
>  		scsi_scan_target(&rport->dev, rport->channel,
> -			rport->scsi_target_id, SCAN_WILD_CARD, 1);
> +				 rport->scsi_target_id, SCAN_WILD_CARD,
> +				 SCSI_SCAN_RESCAN);
>  	}
>  
>  	spin_lock_irqsave(shost->host_lock, flags);
> diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
> index 4414816..7a759a9 100644
> --- a/drivers/scsi/scsi_transport_iscsi.c
> +++ b/drivers/scsi/scsi_transport_iscsi.c
> @@ -1783,6 +1783,7 @@ struct iscsi_scan_data {
>  	unsigned int channel;
>  	unsigned int id;
>  	u64 lun;
> +	enum scsi_scan_mode rescan;
>  };
>  
>  static int iscsi_user_scan_session(struct device *dev, void *data)
> @@ -1819,7 +1820,7 @@ static int iscsi_user_scan_session(struct device *dev, void *data)
>  		    (scan_data->id == SCAN_WILD_CARD ||
>  		     scan_data->id == id))
>  			scsi_scan_target(&session->dev, 0, id,
> -					 scan_data->lun, 1);
> +					 scan_data->lun, scan_data->rescan);
>  	}
>  
>  user_scan_exit:
> @@ -1836,6 +1837,7 @@ static int iscsi_user_scan(struct Scsi_Host *shost, uint channel,
>  	scan_data.channel = channel;
>  	scan_data.id = id;
>  	scan_data.lun = lun;
> +	scan_data.rescan = SCSI_SCAN_MANUAL;
>  
>  	return device_for_each_child(&shost->shost_gendev, &scan_data,
>  				     iscsi_user_scan_session);
> @@ -1852,6 +1854,7 @@ static void iscsi_scan_session(struct work_struct *work)
>  	scan_data.channel = 0;
>  	scan_data.id = SCAN_WILD_CARD;
>  	scan_data.lun = SCAN_WILD_CARD;
> +	scan_data.rescan = SCSI_SCAN_RESCAN;
>  
>  	iscsi_user_scan_session(&session->dev, &scan_data);
>  	atomic_dec(&ihost->nr_scans);
> diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
> index b6f958193..3f0ff07 100644
> --- a/drivers/scsi/scsi_transport_sas.c
> +++ b/drivers/scsi/scsi_transport_sas.c
> @@ -1614,7 +1614,8 @@ int sas_rphy_add(struct sas_rphy *rphy)
>  		else
>  			lun = 0;
>  
> -		scsi_scan_target(&rphy->dev, 0, rphy->scsi_target_id, lun, 0);
> +		scsi_scan_target(&rphy->dev, 0, rphy->scsi_target_id, lun,
> +				 SCSI_SCAN_INITIAL);
>  	}
>  
>  	return 0;
> @@ -1739,8 +1740,8 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel,
>  
>  		if ((channel == SCAN_WILD_CARD || channel == 0) &&
>  		    (id == SCAN_WILD_CARD || id == rphy->scsi_target_id)) {
> -			scsi_scan_target(&rphy->dev, 0,
> -					 rphy->scsi_target_id, lun, 1);
> +			scsi_scan_target(&rphy->dev, 0, rphy->scsi_target_id,
> +					 lun, SCSI_SCAN_MANUAL);
>  		}
>  	}
>  	mutex_unlock(&sas_host->lock);
> diff --git a/drivers/scsi/snic/snic_disc.c b/drivers/scsi/snic/snic_disc.c
> index 5f63217..5f48795 100644
> --- a/drivers/scsi/snic/snic_disc.c
> +++ b/drivers/scsi/snic/snic_disc.c
> @@ -171,7 +171,7 @@ snic_scsi_scan_tgt(struct work_struct *work)
>  			 tgt->channel,
>  			 tgt->scsi_tgt_id,
>  			 SCAN_WILD_CARD,
> -			 1);
> +			 SCSI_SCAN_RESCAN);
>  
>  	spin_lock_irqsave(shost->host_lock, flags);
>  	tgt->flags &= ~SNIC_TGT_SCAN_PENDING;
> diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
> index c067019..61341d3 100644
> --- a/include/scsi/scsi_device.h
> +++ b/include/scsi/scsi_device.h
> @@ -50,6 +50,12 @@ enum scsi_device_state {
>  	SDEV_CREATED_BLOCK,	/* same as above but for created devices */
>  };
>  
> +enum scsi_scan_mode {
> +	SCSI_SCAN_INITIAL = 0,
> +	SCSI_SCAN_RESCAN,
> +	SCSI_SCAN_MANUAL,
> +};
> +
>  enum scsi_device_event {
>  	SDEV_EVT_MEDIA_CHANGE	= 1,	/* media has changed */
>  	SDEV_EVT_INQUIRY_CHANGE_REPORTED,		/* 3F 03  UA reported */
> @@ -391,7 +397,8 @@ extern void scsi_device_resume(struct scsi_device *sdev);
>  extern void scsi_target_quiesce(struct scsi_target *);
>  extern void scsi_target_resume(struct scsi_target *);
>  extern void scsi_scan_target(struct device *parent, unsigned int channel,
> -			     unsigned int id, u64 lun, int rescan);
> +			     unsigned int id, u64 lun,
> +			     enum scsi_scan_mode rescan);
>  extern void scsi_target_reap(struct scsi_target *);
>  extern void scsi_target_block(struct device *);
>  extern void scsi_target_unblock(struct device *, enum scsi_device_state);

Reviewed-by: Ewan D. Milne <emilne@xxxxxxxxxx>


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux