NetBSD-Bugs archive

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

Re: kern/41725 (uvm fault and problems unmounting file sytems at shutdown)



On Sat, Jul 25, 2009 at 11:26:56PM +0000, dyoung%NetBSD.org@localhost wrote:
> Synopsis: uvm fault and problems unmounting file sytems at shutdown
> 
> Responsible-Changed-From-To: kern-bug-people->dyoung
> Responsible-Changed-By: dyoung%NetBSD.org@localhost
> Responsible-Changed-When: Sat, 25 Jul 2009 23:26:55 +0000
> Responsible-Changed-Why:
> I see the bug in md(4).  I know how to fix it.

Try this patch.  It maintains the openmask as a disk is supposed to.

Dave

-- 
David Young             OJC Technologies
dyoung%ojctech.com@localhost      Urbana, IL * (217) 278-3933
Index: sys/dev/md.c
===================================================================
RCS file: /cvsroot/src/sys/dev/md.c,v
retrieving revision 1.59
diff -p -u -u -p -r1.59 md.c
--- sys/dev/md.c        19 May 2009 20:25:41 -0000      1.59
+++ sys/dev/md.c        26 Jul 2009 01:12:37 -0000
@@ -59,6 +59,7 @@ __KERNEL_RCSID(0, "$NetBSD: md.c,v 1.59 
 #include <sys/bufq.h>
 #include <sys/device.h>
 #include <sys/disk.h>
+#include <sys/stat.h>
 #include <sys/proc.h>
 #include <sys/conf.h>
 #include <sys/disklabel.h>
@@ -243,18 +244,23 @@ static int
 mdopen(dev_t dev, int flag, int fmt, struct lwp *l)
 {
        int unit;
+       int part = DISKPART(dev);
+       int pmask = 1 << part;
        struct md_softc *sc;
+       struct disk *dk;
 
        unit = MD_UNIT(dev);
        sc = device_lookup_private(&md_cd, unit);
        if (sc == NULL)
                return ENXIO;
 
+       dk = &sc->sc_dkdev;
+
        /*
         * The raw partition is used for ioctl to configure.
         */
-       if (DISKPART(dev) == RAW_PART)
-               return 0;
+       if (part == RAW_PART)
+               goto ok;
 
 #ifdef MEMORY_DISK_HOOKS
        /* Call the open hook to allow loading the device. */
@@ -268,13 +274,52 @@ mdopen(dev_t dev, int flag, int fmt, str
        if (sc->sc_type == MD_UNCONFIGURED)
                return ENXIO;
 
+ok:
+       /* XXX duplicates code in dk_open().  Call dk_open(), instead? */
+       mutex_enter(&dk->dk_openlock);
+       /* Mark our unit as open. */
+       switch (fmt) {
+       case S_IFCHR:
+               dk->dk_copenmask |= pmask;
+               break;
+       case S_IFBLK:
+               dk->dk_bopenmask |= pmask;
+               break;
+       }
+
+       dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask;
+
+       mutex_exit(&dk->dk_openlock);
        return 0;
 }
 
 static int
 mdclose(dev_t dev, int flag, int fmt, struct lwp *l)
 {
+       int part = DISKPART(dev);
+       int pmask = 1 << part;
+       struct md_softc *sc;
+       struct disk *dk;
+
+       sc = device_lookup_private(&md_cd, MD_UNIT(dev));
+       if (sc == NULL)
+               return ENXIO;
+
+       dk = &sc->sc_dkdev;
+
+       mutex_enter(&dk->dk_openlock);
+
+       switch (fmt) {
+       case S_IFCHR:
+               dk->dk_copenmask &= ~pmask;
+               break;
+       case S_IFBLK:
+               dk->dk_bopenmask &= ~pmask;
+               break;
+       }
+       dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask;
 
+       mutex_exit(&dk->dk_openlock);
        return 0;
 }
 


Home | Main Index | Thread Index | Old Index