Subject: Re: kern/35457: can't mount msdos fs on floppy anymore
To: None <gnats-bugs@NetBSD.org>
From: Christian Biere <christianbiere@gmx.de>
List: netbsd-bugs
Date: 01/21/2007 23:25:44
> mount_msdos: /dev/fd0a on /mnt/tmp: Inappropriate ioctl for device
> 
> Tracing mount_msdos:
> 
>   5936  1 mount_msdos CALL  mount(0x8049222,0xbfbfebee,0,0xbfbfe964)
>   5936  1 mount_msdos NAMI  "/mnt/tmp"
>   5936  1 mount_msdos NAMI  "/dev/fd0a"
>   5936  1 mount_msdos RET   mount -1 errno 25 Inappropriate ioctl for device

I can't tell whether the following is a complete fix but it seems to restore
the original behaviour with respect to floppies. I've checked it under qemu.

--- /sys/fs/msdosfs/msdosfs_vfsops.c.orig	2006-12-26 15:47:02.000000000 +0100
+++ /sys/fs/msdosfs/msdosfs_vfsops.c	2007-01-21 22:58:58.000000000 +0100
@@ -428,6 +428,7 @@
 	u_int8_t SecPerClust;
 	int	ronly, error;
 	int	bsize = 0, dtype = 0, tmp;
+	uint32_t p_size;
 
 	/* Flush out any old buffers remaining from a previous use. */
 	if ((error = vinvalbuf(devvp, V_SAVE, l->l_cred, l, 0, 0)) != 0)
@@ -449,12 +450,20 @@
 	 * Let's root them out...
 	 */
 	error = VOP_IOCTL(devvp, DIOCGPART, &dpart, FREAD, NOCRED, l);
-	if (error)
-		goto error_exit;
-	if (argp->flags & MSDOSFSMNT_GEMDOSFS) {
+	if (error) {
+		if (error != ENOTTY)
+			goto error_exit;
+		tmp = FS_MSDOS;
+		dtype = DTYPE_FLOPPY;
+		bsize = 512;
+		p_size = -1;
+	} else {
 		tmp   = dpart.part->p_fstype;
 		dtype = dpart.disklab->d_type;
 		bsize = dpart.disklab->d_secsize;
+		p_size = dpart.part->p_size;
+	}
+	if (argp->flags & MSDOSFSMNT_GEMDOSFS) {
 		if (bsize != 512 || (dtype!=DTYPE_FLOPPY && tmp!=FS_MSDOS)) {
 			error = EINVAL;
 			goto error_exit;
@@ -465,8 +474,7 @@
 	 * Read the boot sector of the filesystem, and then check the
 	 * boot signature.  If not a dos boot sector then error out.
 	 */
-	if ((error = bread(devvp, 0, dpart.disklab->d_secsize, NOCRED,
-	    &bp)) != 0)
+	if ((error = bread(devvp, 0, bsize, NOCRED, &bp)) != 0)
 		goto error_exit;
 	bp->b_flags |= B_AGE;
 	bsp = (union bootsector *)bp->b_data;
@@ -565,7 +573,7 @@
 		  || (pmp->pm_BytesPerSec & (pmp->pm_BytesPerSec - 1))
 		  || (pmp->pm_HugeSectors == 0)
 		  || (pmp->pm_HugeSectors * (pmp->pm_BytesPerSec / bsize)
-							> dpart.part->p_size)
+							> p_size)
 		   ) {
 			error = EINVAL;
 			goto error_exit;