I got a little bored earlier while looking for something to write about in this month’s kernel hacking column. I came across a post from Evgeny Stambulchik which amused me because it referred to a bug that’s been present in Linux for donkey’s years and either nobody’s noticed or nobody thought it was worth fixing. The problem is experienced by mounting a floppy that’s been write protected and then doing:
mount -o remount,rw /dev/fd0
(or whatever). This should fail on a write protected disk, but it doesn’t because do_remount_sb thinks everything is ok when it checks the backing block dev to see if it is writeable (it is). Unfortunately, it’s not actually trivial for the aforementioned function to check whether the backing device itself is writeable (something missing in VFS?). So you bodge it by having the floppy_open function hack up the gendisk’s view of it’s read/write policy per this posting…
Evgeny Stambulchik found that doing the following always worked:
# mount /dev/fd0 /mnt/floppy/
mount: block device /dev/fd0 is write-protected, mounting read-only
# mount -o remount,rw /mnt/floppy
# echo $?
0
This is the case because the block device /dev/fd0 is writeable but the
floppy disk is marked protected. A fix is to simply have floppy_open
mark the underlying gendisk policy according to reality (since the VFS
doesn't provide a way for do_remount_sb to inquire as to the current
device status).
Signed-off-by: Jon Masters <jcm@jonmasters.org>
--- linux-2.6.14/drivers/block/floppy.c 2005-10-28 01:02:08.000000000
+0100
+++ linux-2.6.14_new/drivers/block/floppy.c 2005-10-29
18:14:47.000000000 +0100
@@ -3714,6 +3714,13 @@
USETF(FD_VERIFY);
}
+ /* set underlying gendisk policy to reflect real ro/rw status */
+ if (UTESTF(FD_DISK_WRITABLE)) {
+ inode->i_bdev->bd_disk->policy = 0;
+ } else {
+ inode->i_bdev->bd_disk->policy = 1;
+ }
+
if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
goto out2;
Jon.