NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/41078: mounting ext2fs via vnd causes LOCKDEBUG panic



> >Synopsis:       mounting ext2fs via vnd causes LOCKDEBUG panic
 :
> panic() at netbsd:panic+0x289
> lockdebug_abort1() at netbsd:lockdebug_abort1+0xd3
> rw_exit() at netbsd:rw_exit+0xe9
> vlockmgr() at netbsd:vlockmgr+0xd8
> VOP_UNLOCK() at netbsd:VOP_UNLOCK+0x64
> spec_open() at netbsd:spec_open+0x340
> VOP_OPEN() at netbsd:VOP_OPEN+0x62
> ext2fs_mount() at netbsd:ext2fs_mount+0x25a
> VFS_MOUNT() at netbsd:VFS_MOUNT+0x44
> do_sys_mount() at netbsd:do_sys_mount+0x62d
> sys___mount50() at netbsd:sys___mount50+0x33
> syscall() at netbsd:syscall+0xb6

This is not ext2fs or vnd(4) specific at all.

"mount_ffs /dev/wd7i /mnt" (where no wd7 disk)
on a LOCKDEBUG kernel is enough to cause this panic.

spec_open() in spec_vnops.c tries to call module_autoload()
if bdev_open() returns ENXIO (== device not configured),
but bdev_open() could return ENXIO even if the driver is
already loaded or builtin. (due to no device, no vnconfig(8) etc.)

The following patch seems to fix the panic and
vnd.kmod without builtin vnd still works properly,
but I wonder if it's worth to have some helper functions
in kern/subr_devsw.c for module_autoload() calls on demand.

---
Index: spec_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/specfs/spec_vnops.c,v
retrieving revision 1.124
diff -u -r1.124 spec_vnops.c
--- spec_vnops.c        25 Apr 2009 15:06:32 -0000      1.124
+++ spec_vnops.c        11 Sep 2009 16:28:28 -0000
@@ -405,11 +405,20 @@
                        vp->v_vflag |= VV_ISTTY;
                VOP_UNLOCK(vp, 0);
                do {
+                       const struct cdevsw *cdev;
+
                        gen = module_gen;
                        error = cdev_open(dev, ap->a_mode, S_IFCHR, l);
                        if (error != ENXIO)
                                break;
                        
+                       /* Check if we already have a valid driver */
+                       mutex_enter(&device_lock);
+                       cdev = cdevsw_lookup(dev);
+                       mutex_exit(&device_lock);
+                       if (cdev != NULL)
+                               break;
+
                        /* Get device name from devsw_conv array */
                        if ((name = cdevsw_getname(major(dev))) == NULL)
                                break;
@@ -447,11 +456,20 @@
                sd->sd_bdevvp = vp;
                mutex_exit(&device_lock);
                do {
+                       const struct bdevsw *bdev;
+
                        gen = module_gen;
                        error = bdev_open(dev, ap->a_mode, S_IFBLK, l);
                        if (error != ENXIO)
                                break;
 
+                       /* Check if we already have a valid driver */
+                       mutex_enter(&device_lock);
+                       bdev = bdevsw_lookup(dev);
+                       mutex_exit(&device_lock);
+                       if (bdev != NULL)
+                               break;
+
                        /* Get device name from devsw_conv array */
                        if ((name = bdevsw_getname(major(dev))) == NULL)
                                break;

---
Izumi Tsutsui


Home | Main Index | Thread Index | Old Index