SCSI fixes for 4.4-rc3
Subsystems (7)
James Bottomley
maintainerThis is quite a bumper crop of fixes: Three from Arnd correcting various build issues in some configurations, a lock recursion in qla2xxx. Two potentially exploitable issues in hpsa and mvsas, a potential null deref in st, A revert of a bdi registration fix that turned out to cause even more problems, a set of fixes to allow people who only defined MPT2SAS to still work after the mpt2/mpt3sas merger and a couple of fixes for issues turned up by the hyper-v storvsc driver.
The patch is available here:
git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git scsi-fixes
The short changelog is:
Arnd Bergmann (3):
scsi: hpsa: select CONFIG_SCSI_SAS_ATTR
scsi: advansys needs ISA dma api for ISA support
advansys: fix big-endian builds
Bart Van Assche (3):
Revert "scsi: Fix a bdi reregistration race" Fix a memory leak in scsi_host_dev_release()
qla2xxx: Fix rwlock recursion
Dan Carpenter (2):
hpsa: logical vs bitwise AND typo
mvsas: don't allow negative timeouts
Douglas Gilbert (1):
scsi_debug: fix prevent_allow+verify regressions
James Bottomley (1):
mpt3sas: fix Kconfig dependency problem for mpt2sas back compatibility
Martin K. Petersen (4):
mpt3sas: Add dummy Kconfig option for backwards compatibility block/sd: Fix device-imposed transfer length limits
MAINTAINERS: Add myself as co-maintainer of the SCSI subsystem.
sd: Make discard granularity match logical block size when LBPRZ=1
Maurizio Lombardi (1):
st: fix potential null pointer dereference.
Sreekanth Reddy (1):
mpt3sas: Fix use sas_is_tlr_enabled API before enabling MPI2_SCSIIO_CONTROL_TLR_ON flag
Vitaly Kuznetsov (2):
scsi_sysfs: protect against double execution of __scsi_remove_device()
scsi: report 'INQUIRY result too short' once per host
And the diffstat:
MAINTAINERS | 4 ++- block/blk-settings.c | 36 +++++++++---------- block/blk-sysfs.c | 3 ++ drivers/scsi/Kconfig | 2 ++ drivers/scsi/advansys.c | 2 +- drivers/scsi/hosts.c | 11 ++++++ drivers/scsi/hpsa.c | 2 +- drivers/scsi/mpt3sas/Kconfig | 9 +++++ drivers/scsi/mpt3sas/mpt3sas_scsih.c | 3 +- drivers/scsi/mvsas/mv_init.c | 4 +-- drivers/scsi/qla2xxx/qla_nx.c | 3 +- drivers/scsi/scsi_debug.c | 9 ++--- drivers/scsi/scsi_scan.c | 9 +++-- drivers/scsi/scsi_sysfs.c | 22 ++++++------ drivers/scsi/sd.c | 69 +++++++++++++++++++++++++----------- drivers/scsi/sd.h | 1 + drivers/scsi/st.c | 5 +-- include/linux/blkdev.h | 2 +- include/scsi/scsi_host.h | 3 ++ 19 files changed, 129 insertions(+), 70 deletions(-)
With full diff below.
James
---
MAINTAINERS +3 -1
@@ -9411,8 +9411,10 @@ F: include/scsi/sg.h SCSI SUBSYSTEM M: "James E.J. Bottomley" <[email protected]> -L: [email protected] T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git +M: "Martin K. Petersen" <[email protected]> +T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git +L: [email protected] S: Maintained F: drivers/scsi/ F: include/scsi/
block/blk-settings.c +16 -20
@@ -91,7 +91,8 @@ void blk_set_default_limits(struct queue_limits *lim) lim->seg_boundary_mask =BLK_SEG_BOUNDARY_MASK ; lim->virt_boundary_mask =0 ; lim->max_segment_size =BLK_MAX_SEGMENT_SIZE ; - lim->max_sectors = lim->max_hw_sectors =BLK_SAFE_MAX_SECTORS ; + lim->max_sectors = lim->max_dev_sectors = lim->max_hw_sectors = +BLK_SAFE_MAX_SECTORS ; lim->chunk_sectors =0 ; lim->max_write_same_sectors =0 ; lim->max_discard_sectors =0 ;
@@ -127,6 +128,7 @@ void blk_set_stacking_limits(struct queue_limits *lim) lim->max_hw_sectors =UINT_MAX ; lim->max_segment_size =UINT_MAX ; lim->max_sectors =UINT_MAX ; + lim->max_dev_sectors =UINT_MAX ; lim->max_write_same_sectors =UINT_MAX ; }EXPORT_SYMBOL (blk_set_stacking_limits);
@@ -214,8 +216,8 @@ void blk_queue_bounce_limit(struct request_queue *q, u64 max_addr)EXPORT_SYMBOL (blk_queue_bounce_limit);/** -* blk_limits_max_hw_sectors - set hard and soft limit of max sectors for request -* @limits: the queue limits +* blk_queue_max_hw_sectors - set max sectors for a request for this queue +* @q: the request queue for the device * @max_hw_sectors: max hardware sectors in the usual 512b unit * * Description:
@@ -224,13 +226,19 @@ EXPORT_SYMBOL(blk_queue_bounce_limit);* the device driver based upon the capabilities of the I/O * controller. * +* max_dev_sectors is a hard limit imposed by the storage device for +* READ/WRITE requests. It is set by the disk driver. +* * max_sectors is a soft limit imposed by the block layer for * filesystem type requests. This value can be overridden on a * per-device basis in /sys/block/<device>/queue/max_sectors_kb. * The soft limit can not exceed max_hw_sectors. **/ -void blk_limits_max_hw_sectors (struct queue_limits *limits,unsigned int max_hw_sectors) +void blk_queue_max_hw_sectors (struct request_queue *q,unsigned int max_hw_sectors) { +struct queue_limits *limits = &q->limits; +unsigned int max_sectors; +if ((max_hw_sectors <<9 ) <PAGE_CACHE_SIZE ) { max_hw_sectors =1 << (PAGE_CACHE_SHIFT -9 ); printk(KERN_INFO "%s: set to minimum %d\n",
@@ -238,22 +246,9 @@ void blk_limits_max_hw_sectors(struct queue_limits *limits, unsigned int max_hw_ } limits->max_hw_sectors = max_hw_sectors; - limits->max_sectors = min_t(unsigned int, max_hw_sectors, -BLK_DEF_MAX_SECTORS ); -} -EXPORT_SYMBOL (blk_limits_max_hw_sectors); - -/** -* blk_queue_max_hw_sectors - set max sectors for a request for this queue -* @q: the request queue for the device -* @max_hw_sectors: max hardware sectors in the usual 512b unit -* -* Description: -* See description for blk_limits_max_hw_sectors(). -**/ -void blk_queue_max_hw_sectors (struct request_queue *q,unsigned int max_hw_sectors) -{ -blk_limits_max_hw_sectors (&q->limits, max_hw_sectors); + max_sectors =min_not_zero (max_hw_sectors, limits->max_dev_sectors); + max_sectors = min_t(unsigned int, max_sectors, BLK_DEF_MAX_SECTORS); + limits->max_sectors = max_sectors; }EXPORT_SYMBOL (blk_queue_max_hw_sectors);
@@ -527,6 +522,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, t->max_sectors =min_not_zero (t->max_sectors, b->max_sectors); t->max_hw_sectors =min_not_zero (t->max_hw_sectors, b->max_hw_sectors); + t->max_dev_sectors =min_not_zero (t->max_dev_sectors, b->max_dev_sectors); t->max_write_same_sectors =min (t->max_write_same_sectors, b->max_write_same_sectors); t->bounce_pfn =min_not_zero (t->bounce_pfn, b->bounce_pfn);
block/blk-sysfs.c +3 -0
@@ -205,6 +205,9 @@ queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)if (ret <0 )return ret; + max_hw_sectors_kb =min_not_zero (max_hw_sectors_kb, (unsigned long ) + q->limits.max_dev_sectors >>1 ); +if (max_sectors_kb > max_hw_sectors_kb || max_sectors_kb < page_kb)return -EINVAL ;
drivers/scsi/Kconfig +2 -0
@@ -364,6 +364,7 @@ config SCSI_HPSA tristate "HP Smart Array SCSI driver" depends on PCI && SCSI select CHECK_SIGNATURE + select SCSI_SAS_ATTRS help This driver supports HP Smart Array Controllers (circa 2009). It is a SCSI alternative to the cciss driver, which is a block
@@ -499,6 +500,7 @@ config SCSI_ADVANSYS tristate "AdvanSys SCSI support" depends on SCSI depends on ISA || EISA || PCI + depends on ISA_DMA_API || !ISA help This is a driver for all SCSI host adapters manufactured by AdvanSys. It is documented in the kernel source in
drivers/scsi/advansys.c +1 -1
@@ -7803,7 +7803,7 @@ adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,return ASC_BUSY ; } scsiqp->sense_addr =cpu_to_le32 (sense_addr); - scsiqp->sense_len =cpu_to_le32 (SCSI_SENSE_BUFFERSIZE ); + scsiqp->sense_len =SCSI_SENSE_BUFFERSIZE ;/* Build ADV_SCSI_REQ_Q */
drivers/scsi/hosts.c +11 -0
@@ -333,6 +333,17 @@ static void scsi_host_dev_release(struct device *dev)kfree (queuedata); } +if (shost->shost_state ==SHOST_CREATED ) { +/* +* Free the shost_dev device name here if scsi_host_alloc() +* and scsi_host_put() have been called but neither +* scsi_host_add() nor scsi_host_remove() has been called. +* This avoids that the memory allocated for the shost_dev +* name is leaked. +*/ +kfree (dev_name (&shost->shost_dev)); + } +scsi_destroy_command_freelist (shost);if (shost_use_blk_mq (shost)) {if (shost->tag_set.tags)
drivers/scsi/hpsa.c +1 -1
@@ -8671,7 +8671,7 @@ static void hpsa_disable_rld_caching(struct ctlr_info *h)if ((rc !=0 ) || (c->err_info->CommandStatus !=0 )) goto errout; -if (*options &&HPSA_DIAG_OPTS_DISABLE_RLD_CACHING ) +if (*options &HPSA_DIAG_OPTS_DISABLE_RLD_CACHING ) goto out; errout:
drivers/scsi/mpt3sas/Kconfig +9 -0
@@ -71,3 +71,12 @@ config SCSI_MPT3SAS_MAX_SGE MAX_PHYS_SEGMENTS in most kernels. However in SuSE kernels this can be 256. However, it may decreased down to 16. Decreasing this parameter will reduce memory requirements on a per controller instance. + +config SCSI_MPT2SAS + tristate "Legacy MPT2SAS config option" + default n + select SCSI_MPT3SAS + depends on PCI && SCSI + ---help--- + Dummy config option for backwards compatiblity: configure the MPT3SAS + driver instead.
drivers/scsi/mpt3sas/mpt3sas_scsih.c +1 -2
@@ -3905,8 +3905,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)* We do not expose raid functionality to upper layer for warpdrive. */ if (!ioc->is_warpdrive && !scsih_is_raid (&scmd->device->sdev_gendev) - && (sas_device_priv_data->flags &MPT_DEVICE_TLR_ON ) && - scmd->cmd_len !=32 ) + &&sas_is_tlr_enabled (scmd->device) && scmd->cmd_len !=32 ) mpi_control |=MPI2_SCSIIO_CONTROL_TLR_ON ; smid =mpt3sas_base_get_smid_scsiio (ioc, ioc->scsi_io_cb_idx, scmd);
drivers/scsi/mvsas/mv_init.c +2 -2
@@ -758,7 +758,7 @@ mvs_store_interrupt_coalescing(struct device *cdev,struct device_attribute *attr, const char *buffer, size_t size) { - int val = 0; + unsigned int val = 0;struct mvs_info *mvi =NULL ;struct Scsi_Host *shost =class_to_shost (cdev);struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost);
@@ -766,7 +766,7 @@ mvs_store_interrupt_coalescing(struct device *cdev,if (buffer ==NULL )return size; -if (sscanf (buffer,"%d" , &val) !=1 ) +if (sscanf (buffer,"%u" , &val) !=1 )return -EINVAL ;if (val >=0x10000 ) {
drivers/scsi/qla2xxx/qla_nx.c +2 -1
@@ -433,7 +433,7 @@ qla82xx_pci_get_crb_addr_2M(struct qla_hw_data *ha, ulong off_in,if (off_in <QLA82XX_PCI_CRBSPACE )return -1 ; - *off_out = (void __iomem *)(off_in -QLA82XX_PCI_CRBSPACE ); + off_in -=QLA82XX_PCI_CRBSPACE ;/* Try direct map */ m = &crb_128M_2M_map[CRB_BLK (off_in)].sub_block[CRB_SUBBLK (off_in)];
@@ -443,6 +443,7 @@ qla82xx_pci_get_crb_addr_2M(struct qla_hw_data *ha, ulong off_in,return 0 ; }/* Not in direct map, use crb window */ + *off_out = (void __iomem *)off_in;return 1 ; }
drivers/scsi/scsi_debug.c +5 -4
@@ -465,8 +465,9 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEMENT + 1] = { 0} }, {0 ,0 ,0 ,F_INV_OP |FF_RESPOND ,NULL ,NULL ,/* MAINT OUT */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* VERIFY */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {0, 0x2f, 0, F_D_OUT_MAYBE | FF_DIRECT_IO, NULL, NULL, /* VERIFY(10) */ + {10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, + 0, 0, 0, 0, 0, 0} }, {1, 0x7f, 0x9, F_SA_HIGH | F_D_IN | FF_DIRECT_IO, resp_read_dt0, vl_iarr, {32, 0xc7, 0, 0, 0, 0, 0x1f, 0x18, 0x0, 0x9, 0xfe, 0, 0xff, 0xff, 0xff, 0xff} },/* VARIABLE LENGTH, READ(32) */
@@ -477,8 +478,8 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEMENT + 1] = { {10 ,0x13 ,0xff ,0xff ,0 ,0 ,0 ,0xff ,0xff ,0xc7 ,0 ,0 ,0 ,0 ,0 , 0} },/* 20 */ - {0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* ALLOW REMOVAL */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {0, 0x1e, 0, 0, NULL, NULL, /* ALLOW REMOVAL */ + {6, 0, 0, 0, 0x3, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, {0, 0x1, 0, 0, resp_start_stop, NULL, /* REWIND ?? */ {6, 0x1, 0, 0, 0, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, {0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* ATA_PT */
drivers/scsi/scsi_scan.c +6 -3
@@ -701,9 +701,12 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,* strings. */ if (sdev->inquiry_len <36 ) { -sdev_printk (KERN_INFO , sdev, -"scsi scan: INQUIRY result too short (%d)," -" using 36\n" , sdev->inquiry_len); +if (!sdev->host->short_inquiry) { +shost_printk (KERN_INFO , sdev->host, +"scsi scan: INQUIRY result too short (%d)," +" using 36\n" , sdev->inquiry_len); + sdev->host->short_inquiry =1 ; + } sdev->inquiry_len =36 ; }
drivers/scsi/scsi_sysfs.c +11 -11
@@ -1102,6 +1102,14 @@ void __scsi_remove_device(struct scsi_device *sdev) {struct device *dev = &sdev->sdev_gendev; +/* +* This cleanup path is not reentrant and while it is impossible +* to get a new reference with scsi_device_get() someone can still +* hold a previously acquired one. +*/ +if (sdev->sdev_state ==SDEV_DEL ) +return ; +if (sdev->is_visible) {if (scsi_device_set_state (sdev,SDEV_CANCEL ) !=0 )return ;
@@ -1110,7 +1118,9 @@ void __scsi_remove_device(struct scsi_device *sdev)device_unregister (&sdev->sdev_dev);transport_remove_device (dev);scsi_dh_remove_device (sdev); - } +device_del (dev); + }else +put_device (&sdev->sdev_dev);/* * Stop accepting new requests and wait until all queuecommand() and
@@ -1121,16 +1131,6 @@ void __scsi_remove_device(struct scsi_device *sdev)blk_cleanup_queue (sdev->request_queue);cancel_work_sync (&sdev->requeue_work); -/* -* Remove the device after blk_cleanup_queue() has been called such -* a possible bdi_register() call with the same name occurs after -* blk_cleanup_queue() has called bdi_destroy(). -*/ -if (sdev->is_visible) -device_del (dev); -else -put_device (&sdev->sdev_dev); -if (sdev->host->hostt->slave_destroy) sdev->host->hostt->slave_destroy (sdev);transport_destroy_device (dev);
drivers/scsi/sd.c +48 -21
116 lines not on this page · raw message
drivers/scsi/sd.h +1 -0
@@ -67,6 +67,7 @@ struct scsi_disk {atomic_t openers;sector_t capacity;/* size in 512-byte sectors */ u32 max_xfer_blocks; +u32 opt_xfer_blocks;u32 max_ws_blocks;u32 max_unmap_blocks;u32 unmap_granularity;
drivers/scsi/st.c +3 -2
@@ -4083,6 +4083,7 @@ static int create_one_cdev(struct scsi_tape *tape, int mode, int rew) } cdev->owner =THIS_MODULE ; cdev->ops = &st_fops; + STm->cdevs[rew] = cdev; error =cdev_add (cdev, cdev_devno,1 );if (error) {
@@ -4091,7 +4092,6 @@ static int create_one_cdev(struct scsi_tape *tape, int mode, int rew)pr_err ("st%d: Device not attached.\n" , dev_num); goto out_free; } - STm->cdevs[rew] = cdev; i = mode << (4 -ST_NBR_MODE_BITS ); snprintf(name, 10, "%s%s%s", rew ? "n" : "",
@@ -4110,8 +4110,9 @@ static int create_one_cdev(struct scsi_tape *tape, int mode, int rew)return 0 ; out_free:cdev_del (STm->cdevs[rew]); - STm->cdevs[rew] =NULL ; out: + STm->cdevs[rew] =NULL ; + STm->devs[rew] =NULL ;return error; }
include/linux/blkdev.h +1 -1
@@ -254,6 +254,7 @@ struct queue_limits {unsigned long virt_boundary_mask;unsigned int max_hw_sectors; +unsigned int max_dev_sectors;unsigned int chunk_sectors;unsigned int max_sectors;unsigned int max_segment_size;
@@ -958,7 +959,6 @@ extern struct request_queue *blk_init_allocated_queue(struct request_queue *,extern void blk_cleanup_queue (struct request_queue *);extern void blk_queue_make_request (struct request_queue *,make_request_fn *);extern void blk_queue_bounce_limit (struct request_queue *,u64 ); -extern void blk_limits_max_hw_sectors (struct queue_limits *,unsigned int );extern void blk_queue_max_hw_sectors (struct request_queue *,unsigned int );extern void blk_queue_chunk_sectors (struct request_queue *,unsigned int );extern void blk_queue_max_segments (struct request_queue *,unsigned short );
include/scsi/scsi_host.h +3 -0
@@ -668,6 +668,9 @@ struct Scsi_Host { unsigned use_blk_mq:1; unsigned use_cmd_list:1; +/* Host responded with short (<36 bytes) INQUIRY result */ + unsigned short_inquiry:1; +/* * Optional work queue to be utilized by the transport */