Re: [PATCH v2] cdrom, scsi: sr: propagate read-only status to block layer via set_disk_ro()

From: Phillip Potter

Date: Thu Apr 23 2026 - 17:11:37 EST


On Wed, Apr 22, 2026 at 11:32:06AM +0000, Daan De Meyer wrote:
> The cdrom core never calls set_disk_ro() for a registered device, so
> BLKROGET on a CD-ROM device always returns 0 (writable), even when the
> drive has no write capabilities and writes will inevitably fail. This
> causes problems for userspace that relies on BLKROGET to determine
> whether a block device is read-only. For example, systemd's loop device
> setup uses BLKROGET to decide whether to create a loop device with
> LO_FLAGS_READ_ONLY. Without the read-only flag, writes pass through the
> loop device to the CD-ROM and fail with I/O errors. systemd-fsck
> similarly checks BLKROGET to decide whether to run fsck in no-repair
> mode (-n).
>
> The write-capability bits in cdi->mask come from two different sources:
> CDC_DVD_RAM and CDC_CD_RW are populated by the driver from the MODE
> SENSE capabilities page (page 0x2A) before register_cdrom() is called,
> while CDC_MRW_W and CDC_RAM require the MMC GET CONFIGURATION command
> and were only probed by cdrom_open_write() at device open time. This
> meant that any attempt to compute the writable state from the full
> mask at probe time was incorrect, because the GET CONFIGURATION bits
> were still unset (and cdi->mask is initialized such that capabilities
> are assumed present).
>
> Fix this by factoring the GET CONFIGURATION probing out of
> cdrom_open_write() into a new exported helper,
> cdrom_probe_write_features(), and having sr call it from sr_probe()
> right after get_capabilities() has populated the MODE SENSE bits.
> register_cdrom() then calls set_disk_ro() based on the full
> write-capability mask (CDC_DVD_RAM | CDC_MRW_W | CDC_RAM | CDC_CD_RW)
> so the block layer reflects the drive's actual write support. The
> feature queries used (CDF_MRW and CDF_RWRT via GET CONFIGURATION with
> RT=00) report drive-level capabilities that are persistent across
> media, so a single probe before register_cdrom() is sufficient and the
> redundant probe at open time is dropped.
>
> With set_disk_ro() now accurate, the long-vestigial cd->writeable flag
> in sr can go: get_capabilities() used to set cd->writeable based on
> the same four mask bits, but because CDC_MRW_W and CDC_RAM default to
> "capability present" in cdi->mask and aren't touched by MODE SENSE,
> the condition that gated cd->writeable was always true, making it
> unconditionally 1. Replace the corresponding gate in sr_init_command()
> with get_disk_ro(cd->disk), which turns a previously no-op check into
> a real one and also catches kernel-internal bio writers that bypass
> blkdev_write_iter()'s bdev_read_only() check.
>
> The sd driver (SCSI disks) does not have this problem because it
> checks the MODE SENSE Write Protect bit and calls set_disk_ro()
> accordingly. The sr driver cannot use the same approach because the
> MMC specification does not define the WP bit in the MODE SENSE
> device-specific parameter byte for CD-ROM devices.
>
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Signed-off-by: Daan De Meyer <daan@xxxxxxxxxxxx>

Hi Daan,

Thank you for the patch. I will properly review it and build test etc.
this weekend and come back to you, hope that's ok.

Regards,
Phil