[PATCH v10 08/15] scsi: sr: keep queue block sizes in sync with the medium

From: Phil Pemberton

Date: Fri Oct 09 2026 - 12:33:17 EST


sr_probe() sets sdev->sector_size to 2048, but the request queue keeps its
512-byte default until revalidation finds ready media. Booting a COMPAQ
PD-1 LF-1195C with a PD inserted leaves the empty CD LUN with mismatched
block sizes. Later CD reads can fail with "unaligned transfer".

After initial revalidation, set the queue's block sizes to
sdev->sector_size if the logical size differs. Do this before registering
the disk, and unwind the probe if the update fails. Revalidate first so
ready media can supply the actual block size instead of the 2048-byte
guess.

Also set the physical block size and minimum I/O size when revalidating
media. The block layer raises these to the logical block size, but does
not lower them when a later medium has smaller sectors. Updating only
the logical size can therefore leave stale 2048-byte physical and minimum
I/O sizes after inserting 512-byte media or switching between media types.

sr does not discover separate physical or minimum I/O sizes, so keep both
in sync with the medium's reported sector size.

Assisted-by: LLM
Signed-off-by: Phil Pemberton <philpem@xxxxxxxxxxxxx>
---
drivers/scsi/sr.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index c36c54ecd354..28523b0eb659 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -488,6 +488,8 @@ static int sr_revalidate_disk(struct scsi_cd *cd)

lim = queue_limits_start_update(q);
lim.logical_block_size = sector_size;
+ lim.physical_block_size = sector_size;
+ lim.io_min = sector_size;
lim.features |= BLK_FEAT_ROTATIONAL;
return queue_limits_commit_update_frozen(q, &lim);
}
@@ -619,6 +621,7 @@ static void sr_release(struct cdrom_device_info *cdi)
static int sr_probe(struct scsi_device *sdev)
{
struct device *dev = &sdev->sdev_gendev;
+ struct queue_limits lim;
struct gendisk *disk;
struct scsi_cd *cd;
int minor, error;
@@ -701,6 +704,18 @@ static int sr_probe(struct scsi_device *sdev)
if (error)
goto unregister_cdrom;

+ /* If no medium was ready, match the queue to the driver's guess. */
+ if (queue_logical_block_size(sdev->request_queue) != sdev->sector_size) {
+ lim = queue_limits_start_update(sdev->request_queue);
+ lim.logical_block_size = sdev->sector_size;
+ lim.physical_block_size = sdev->sector_size;
+ lim.io_min = sdev->sector_size;
+ error = queue_limits_commit_update_frozen(sdev->request_queue,
+ &lim);
+ if (error)
+ goto unregister_cdrom;
+ }
+
error = device_add_disk(&sdev->sdev_gendev, disk, NULL);
if (error)
goto unregister_cdrom;
--
2.43.0