mirror of
https://github.com/torvalds/linux.git
synced 2026-09-26 10:02:02 +02:00
SCSI fixes on 20260925
Mostly small driver fixes. The biggest fix is the one to the block zone handling which might trip for real or virtual hardware if the number of zones is > 2^32. Signed-off-by: James E.J. Bottomley <James.Bottomley@HansenPartnership.com> -----BEGIN PGP SIGNATURE----- iLgEABMIAGAWIQTnYEDbdso9F2cI+arnQslM7pishQUCarblBBsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDImHGphbWVzLmJvdHRvbWxleUBoYW5zZW5wYXJ0bmVy c2hpcC5jb20ACgkQ50LJTO6YrIXG4wEA0mYHxKLKHGzKMTZhLIQc9LqJ+oAFQfwk sUfhX5kqt+QA+QGx/jrg6DKgC6LLeti8xRD+hkeSCwSPCt98Tg2/ba/O =pQUi -----END PGP SIGNATURE----- Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi Pull SCSI fixes from James Bottomley: "Mostly small driver fixes. The biggest fix is the one to the block zone handling which might trip for real or virtual hardware if the number of zones is > 2^32" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: megaraid_sas: Protect megasas_get_ctrl_info() in megasas_resume() scsi: sd_zbc: Reject disks with too many zones scsi: block: Fix zones_cond out-of-bounds write on zone report scsi: leapraid: Avoid -Wformat-security warning scsi: devinfo: Add BLIST_SKIP_IO_HINTS for EMC Symmetrix scsi: libiscsi_tcp: Check the data direction of a Data-In PDU scsi: ufs: pltfrm: Add quirk for R-Car S4 lacking lanes-per-direction scsi: ufs: core: Keep internal commands dispatchable during error handling
This commit is contained in:
commit
049380360c
|
|
@ -2018,12 +2018,17 @@ static int disk_revalidate_zone_resources(struct gendisk *disk,
|
|||
struct blk_revalidate_zone_args *args)
|
||||
{
|
||||
struct queue_limits *lim = &disk->queue->limits;
|
||||
unsigned long long nr_zones;
|
||||
unsigned int pool_size;
|
||||
int ret = 0;
|
||||
|
||||
args->disk = disk;
|
||||
args->nr_zones =
|
||||
DIV_ROUND_UP_ULL(get_capacity(disk), lim->chunk_sectors);
|
||||
nr_zones = DIV_ROUND_UP_ULL(get_capacity(disk), lim->chunk_sectors);
|
||||
if (nr_zones > UINT_MAX) {
|
||||
pr_warn("%s: Too many zones (%llu)\n", disk->disk_name, nr_zones);
|
||||
return -EINVAL;
|
||||
}
|
||||
args->nr_zones = nr_zones;
|
||||
|
||||
/* Cached zone conditions: 1 byte per zone */
|
||||
args->zones_cond = kzalloc(args->nr_zones, GFP_NOIO);
|
||||
|
|
@ -2131,6 +2136,12 @@ static int blk_revalidate_zone_cond(struct blk_zone *zone, unsigned int idx,
|
|||
{
|
||||
enum blk_zone_cond cond = zone->cond;
|
||||
|
||||
if (idx >= args->nr_zones) {
|
||||
pr_warn("%s: Zone report index %u exceeds zone count %u\n",
|
||||
args->disk->disk_name, idx, args->nr_zones);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check that the zone condition is consistent with the zone type. */
|
||||
switch (cond) {
|
||||
case BLK_ZONE_COND_NOT_WP:
|
||||
|
|
|
|||
|
|
@ -554,7 +554,6 @@ struct leapraid_fw_evt_work {
|
|||
/**
|
||||
* struct leapraid_fw_evt_struct - Firmware event handling structure
|
||||
*
|
||||
* @fw_evt_name: Name of the firmware event.
|
||||
* @fw_evt_thread: Workqueue used for processing firmware events.
|
||||
* @fw_evt_lock: Spinlock protecting access to the firmware event list.
|
||||
* @fw_evt_list: Linked list of pending firmware events.
|
||||
|
|
@ -565,7 +564,6 @@ struct leapraid_fw_evt_work {
|
|||
*/
|
||||
struct leapraid_fw_evt_struct {
|
||||
u32 leapraid_evt_masks[4];
|
||||
char fw_evt_name[48];
|
||||
struct workqueue_struct *fw_evt_thread;
|
||||
spinlock_t fw_evt_lock; /* protects firmware event */
|
||||
struct list_head fw_evt_list;
|
||||
|
|
|
|||
|
|
@ -2054,12 +2054,10 @@ static int leapraid_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
shost->transportt = leapraid_transport_template;
|
||||
shost->unique_id = adapter->adapter_attr.id;
|
||||
|
||||
snprintf(adapter->fw_evt_s.fw_evt_name,
|
||||
sizeof(adapter->fw_evt_s.fw_evt_name),
|
||||
"fw_event_%s%d", LEAPRAID_DRIVER_NAME,
|
||||
adapter->adapter_attr.id);
|
||||
adapter->fw_evt_s.fw_evt_thread =
|
||||
alloc_ordered_workqueue(adapter->fw_evt_s.fw_evt_name, 0);
|
||||
alloc_ordered_workqueue("fw_event_%s%d", 0,
|
||||
LEAPRAID_DRIVER_NAME,
|
||||
adapter->adapter_attr.id);
|
||||
if (!adapter->fw_evt_s.fw_evt_thread) {
|
||||
dev_err(&adapter->pdev->dev,
|
||||
"%s: Failed to create fw event workqueue\n", __func__);
|
||||
|
|
|
|||
|
|
@ -480,6 +480,9 @@ static int iscsi_tcp_data_in(struct iscsi_conn *conn, struct iscsi_task *task)
|
|||
int datasn = be32_to_cpu(rhdr->datasn);
|
||||
unsigned total_in_length = task->sc->sdb.length;
|
||||
|
||||
if (task->sc->sc_data_direction != DMA_FROM_DEVICE)
|
||||
return ISCSI_ERR_PROTO;
|
||||
|
||||
/*
|
||||
* lib iscsi will update this in the completion handling if there
|
||||
* is status.
|
||||
|
|
|
|||
|
|
@ -7886,7 +7886,9 @@ megasas_resume(struct device *dev)
|
|||
goto fail_init_mfi;
|
||||
}
|
||||
|
||||
if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS)
|
||||
scoped_guard(mutex, &instance->reset_mutex)
|
||||
rval = megasas_get_ctrl_info(instance);
|
||||
if (rval != DCMD_SUCCESS)
|
||||
goto fail_init_mfi;
|
||||
|
||||
tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ static struct {
|
|||
{"DGC", "DISK", NULL, BLIST_SPARSELUN}, /* EMC CLARiiON, no storage on LUN 0 */
|
||||
{"EMC", "Invista", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
|
||||
{"EMC", "SYMMETRIX", NULL, BLIST_SPARSELUN | BLIST_LARGELUN |
|
||||
BLIST_REPORTLUN2 | BLIST_RETRY_ITF},
|
||||
BLIST_REPORTLUN2 | BLIST_RETRY_ITF | BLIST_SKIP_IO_HINTS},
|
||||
{"EMULEX", "MD21/S2 ESDI", NULL, BLIST_SINGLELUN},
|
||||
{"easyRAID", "16P", NULL, BLIST_NOREPORTLUN},
|
||||
{"easyRAID", "X6P", NULL, BLIST_NOREPORTLUN},
|
||||
|
|
|
|||
|
|
@ -589,7 +589,7 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp)
|
|||
int sd_zbc_read_zones(struct scsi_disk *sdkp, struct queue_limits *lim,
|
||||
u8 buf[SD_BUF_SIZE])
|
||||
{
|
||||
unsigned int nr_zones;
|
||||
u64 nr_zones;
|
||||
u32 zone_blocks = 0;
|
||||
int ret;
|
||||
|
||||
|
|
@ -621,6 +621,12 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, struct queue_limits *lim,
|
|||
goto err;
|
||||
|
||||
nr_zones = round_up(sdkp->capacity, zone_blocks) >> ilog2(zone_blocks);
|
||||
if (nr_zones > INT_MAX) {
|
||||
sd_printk(KERN_ERR, sdkp, "Too many zones (%llu)\n",
|
||||
nr_zones);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
sdkp->early_zone_info.nr_zones = nr_zones;
|
||||
sdkp->early_zone_info.zone_blocks = zone_blocks;
|
||||
|
||||
|
|
|
|||
|
|
@ -6817,11 +6817,17 @@ static void ufshcd_err_handling_prepare(struct ufs_hba *hba)
|
|||
}
|
||||
/* Wait for ongoing ufshcd_queuecommand() calls to finish. */
|
||||
blk_mq_quiesce_tagset(&hba->host->tag_set);
|
||||
/*
|
||||
* Internal commands are submitted on the pseudo SCSI device. Let them
|
||||
* through so that the error handler can recover the link.
|
||||
*/
|
||||
blk_mq_unquiesce_queue(hba->host->pseudo_sdev->request_queue);
|
||||
cancel_work_sync(&hba->eeh_work);
|
||||
}
|
||||
|
||||
static void ufshcd_err_handling_unprepare(struct ufs_hba *hba)
|
||||
{
|
||||
blk_mq_quiesce_queue_nowait(hba->host->pseudo_sdev->request_queue);
|
||||
blk_mq_unquiesce_tagset(&hba->host->tag_set);
|
||||
ufshcd_release(hba);
|
||||
if (ufshcd_is_clkscaling_supported(hba))
|
||||
|
|
|
|||
|
|
@ -206,7 +206,11 @@ static void ufshcd_init_lanes_per_dir(struct ufs_hba *hba)
|
|||
dev_dbg(hba->dev,
|
||||
"%s: failed to read lanes-per-direction, ret=%d\n",
|
||||
__func__, ret);
|
||||
hba->lanes_per_direction = UFSHCD_DEFAULT_LANES_PER_DIRECTION;
|
||||
/* Old R-Car S4 DTBs lack "lanes-per-direction = <1>" */
|
||||
if (of_device_is_compatible(dev->of_node, "renesas,r8a779f0-ufs"))
|
||||
hba->lanes_per_direction = 1;
|
||||
else
|
||||
hba->lanes_per_direction = UFSHCD_DEFAULT_LANES_PER_DIRECTION;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user