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:
Linus Torvalds 2026-09-25 14:41:52 -07:00
commit 049380360c
9 changed files with 41 additions and 13 deletions

View File

@ -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:

View File

@ -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;

View File

@ -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__);

View File

@ -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.

View File

@ -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,

View File

@ -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},

View File

@ -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;

View File

@ -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))

View File

@ -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;
}
}