Oops with msdosfs (a possible fix included)

T Taneli Vahakangas (vahakang@cc.helsinki.fi)
Thu, 21 Aug 1997 01:37:18 +0300 (EET DST)


Hello,

A strange thing happened a while back, when I was trying to mount a
defect msdosfs (i.e. didn't run mkdosfs :-) through the loop device:

# mount -t msdos ./disk_image /mnt/a -o loop=/dev/loop1
[MS-DOS FS Rel. 12,FAT 0,check=n,conv=b,uid=0,gid=0,umask=022,bmap]
[me=0x0,cs=0,#f=0,fs=0,fl=0,ds=0,de=0,data=0,se=0,ts=0,ls=0]
Transaction block size = 512
VFS: Can't find a valid MSDOS filesystem on dev 07:01.
Unable to handle kernel NULL pointer dereference at virtual address 00000040
current->tss.cr3 = 03149000, %cr3 = 03149000
*pde = 00000000
Oops: 0002
CPU: 0
EIP: 0010:[<c0140dec>]
EFLAGS: 00010296
eax: 00000000 ebx: c01b89b0 ecx: c019bcd8 edx: 00000000
esi: 00000701 edi: c019e270 ebp: 00000701 esp: c314bef0
ds: 0018 es: 0018 ss: 0018
Process mount (pid: 333, process nr: 20, stackpage=c314b000)
Stack: c01b89b0 c01261b2 c01b89b0 c3025000 00000000 c3dda5e0 c4800701 00000701
00000000 c0126577 00000701 c018a82c 00000000 c3025000 00000000 00000701
c480d014 080514a8 c303d8dc c0126aa9 00000701 08051510 080514a8 c018a82c
Call Trace: [<c01261b2>] [<c4800701>] [<c0126577>] [<c018a82c>] [<c480d014>] [<c0126aa9>] [<c018a82c>]
[<c018a82c>] [<c010944a>]
Code: c7 40 40 e8 e2 19 c0 89 d0 5b c3 90 83 ec 0c 57 56 53 8b 7c
Using `/usr/src/linux/System.map' to map addresses to symbols.

>>EIP: c0140dec <msdos_read_super+24/30>
Trace: c01261b2 <read_super+a6/d0>
Trace: c4800701
Trace: c0126577 <do_mount+b3/124>
Trace: c018a82c <tvecs+3b1c/4394>
Trace: c480d014
Trace: c0126aa9 <sys_mount+299/2ec>
Trace: c018a82c <tvecs+3b1c/4394>
Trace: c018a82c <tvecs+3b1c/4394>
Trace: c010944a <system_call+3a/40>

Code: c0140dec <msdos_read_super+24/30>
Code: c0140dec <msdos_read_super+24/30> c7 40 40 e8 e2 movl $0xc019e2e8,0x40(%eax)
Code: c0140df1 <msdos_read_super+29/30> 19 c0
Code: c0140df3 <msdos_read_super+2b/30> 89 d0 movl %edx,%eax
Code: c0140df5 <msdos_read_super+2d/30> 5b popl %ebx
Code: c0140dfc <msdos_lookup+4/138> c3 ret
Code: c0140dfd <msdos_lookup+5/138> 90 nop
Code: c0140dfe <msdos_lookup+6/138> 83 ec 0c subl $0xc,%esp
Code: c0140e01 <msdos_lookup+9/138> 57 pushl %edi
Code: c0140e02 <msdos_lookup+a/138> 56 pushl %esi
Code: c0140e03 <msdos_lookup+b/138> 53 pushl %ebx
Code: c0140e04 <msdos_lookup+c/138> 8b 7c 00 90 movl 0xffffff90(%eax,%eax,1),%edi
Code: c0140e0e <msdos_lookup+16/138> 90 nop
Code: c0140e0f <msdos_lookup+17/138> 90 nop

Would the following patch correct it, correctly?

--- linux/fs/msdos/namei.c.orig Wed Aug 20 23:47:15 1997
+++ linux/fs/msdos/namei.c Wed Aug 20 23:47:55 1997
@@ -232,8 +232,11 @@

sb->s_op = &msdos_sops;
res = fat_read_super(sb, data, silent);
- if (res == NULL)
+ if (res == NULL) {
+ sb->s_dev = 0;
MOD_DEC_USE_COUNT;
+ return NULL;
+ }
sb->s_root->d_op = &msdos_dentry_operations;
return res;
}

It is against 2.1.51 and it seems like doing the right thing:

# mount -t msdos ./disk_image /mnt/a -o loop=/dev/loop1
mount: wrong fs type, bad option, bad superblock on /dev/loop1,
or too many mounted file systems

(Disclaimer: I don't know what I was doing. I shamelessly looked at
vfat/namei.c and copied the two lines and braces from there.)

Taneli