diff options
author | Pete Zaitcev <zaitcev@redhat.com> | 2005-07-05 21:18:08 -0400 |
---|---|---|
committer | James Bottomley <jejb@titanic.(none)> | 2005-08-28 12:14:12 -0400 |
commit | 51490c89f95b8581782e9baa855da166441852be (patch) | |
tree | 3be27d5e30c114d5d69fe21a4a079a64f2016354 /drivers/scsi/sr.h | |
parent | 8224bfa84d510630b40ea460b2bb380c91acb8ae (diff) |
[SCSI] sr.c: Fix getting wrong size
Here's the problem. Try to do this on 2.6.12:
- Kill udev and HAL
- Insert a CD-ROM into a SCSI or USB CD-ROM drive
- Run dd if=/dev/scd0
- cat /sys/block/sr0/size
- Eject the CD, insert a different one
- Run dd if=/dev/scd0
This is likely to do "access beyond the end of device", if you let it
- cat /sys/block/sr0/size
This shows the size of a previous CD, even though dd was supposed
to revalidate the device.
- Run dd if=/dev/scd0
The second run of dd works correctly!
The bug was introduced in 2.5.31, when Al fixes the recursive opens
in partitioning. Before, the code worked like this:
- Block layer called cdrom_open directly
- cdrom_open called sr_open
- sr_open called check_disk_change
- check_disk_change called sr_media_change
- sr_media_change did cd->needs_disk_change=1
- before returning sr_open tested cd->needs_disk_change
and called get_sector_size.
In 2.6.12, the check_disk_change is called from cdrom_open only. Thus:
- Block layer calls sr_bd_open
- sr_bd_open calls cdrom_open
- cdrom_open calls sr_open
- sr_open tests cd->needs_disk_change, which wasn't set yet; returns
- cdrom_open calls check_disk_change
- check_disk_change calls sr_media_change
- sr_media_change does cd->needs_disk_change=1, but nobody cares
Acked by: Alexander Viro <aviro@redhat.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/sr.h')
-rw-r--r-- | drivers/scsi/sr.h | 1 |
1 files changed, 0 insertions, 1 deletions
diff --git a/drivers/scsi/sr.h b/drivers/scsi/sr.h index 0b3178007203..d2bcd99c272f 100644 --- a/drivers/scsi/sr.h +++ b/drivers/scsi/sr.h | |||
@@ -33,7 +33,6 @@ typedef struct scsi_cd { | |||
33 | struct scsi_device *device; | 33 | struct scsi_device *device; |
34 | unsigned int vendor; /* vendor code, see sr_vendor.c */ | 34 | unsigned int vendor; /* vendor code, see sr_vendor.c */ |
35 | unsigned long ms_offset; /* for reading multisession-CD's */ | 35 | unsigned long ms_offset; /* for reading multisession-CD's */ |
36 | unsigned needs_sector_size:1; /* needs to get sector size */ | ||
37 | unsigned use:1; /* is this device still supportable */ | 36 | unsigned use:1; /* is this device still supportable */ |
38 | unsigned xa_flag:1; /* CD has XA sectors ? */ | 37 | unsigned xa_flag:1; /* CD has XA sectors ? */ |
39 | unsigned readcd_known:1; /* drive supports READ_CD (0xbe) */ | 38 | unsigned readcd_known:1; /* drive supports READ_CD (0xbe) */ |