cdrom, scsi: sr: propagate read-only status to block layer via set_disk_ro()#762
cdrom, scsi: sr: propagate read-only status to block layer via set_disk_ro()#762blktests-ci[bot] wants to merge 1 commit intolinus-master_basefrom
Conversation
|
Upstream branch: b4e0758 |
ceec5ed to
3b54e52
Compare
|
Upstream branch: 6596a02 |
dd666b9 to
6ae66a7
Compare
3b54e52 to
6a0b974
Compare
|
Upstream branch: 507bd4b |
6ae66a7 to
64c4f54
Compare
6a0b974 to
59ca59b
Compare
|
Upstream branch: dd6c438 |
64c4f54 to
ab4b8b5
Compare
94f0438 to
857ada9
Compare
|
Upstream branch: dd6c438 |
ab4b8b5 to
5bb9542
Compare
|
Upstream branch: dd6c438 |
5bb9542 to
62e866e
Compare
|
Upstream branch: dd6c438 |
…sk_ro() 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: 1da177e ("Linux-2.6.12-rc2") Signed-off-by: Daan De Meyer <[email protected]> Reviewed-by: Phillip Potter <[email protected]> Reviewed-by: Martin K. Petersen <[email protected]>
62e866e to
405a176
Compare
Pull request for series with
subject: cdrom, scsi: sr: propagate read-only status to block layer via set_disk_ro()
version: 2
url: https://patchwork.kernel.org/project/linux-block/list/?series=1084246