Hello hackers...

With attached patch unloading md(4) module is possible.
It also cleans up big part of code according to style(9).

Patch is also avaliable at:

        http://garage.freebsd.pl/patches/md.c.patch

-- 
Pawel Jakub Dawidek                       [EMAIL PROTECTED]
UNIX Systems Programmer/Administrator     http://garage.freebsd.pl
Am I Evil? Yes, I Am!                     http://cerber.sourceforge.net
With this patch it is possible to unload md.ko module and it contains
a lot of cleanups (style(9)) and simplifies.

--- md.c.orig   Sun Dec 28 11:12:22 2003
+++ md.c        Sun Jan 11 16:41:23 2004
@@ -98,7 +98,7 @@
 static MALLOC_DEFINE(M_MD, "MD disk", "Memory Disk");
 static MALLOC_DEFINE(M_MDSECT, "MD sectors", "Memory Disk Sectors");
 
-static int md_debug;
+static int md_debug = 0;
 SYSCTL_INT(_debug, OID_AUTO, mddebug, CTLFLAG_RW, &md_debug, 0, "");
 
 #if defined(MD_ROOT) && defined(MD_ROOT_SIZE)
@@ -107,13 +107,16 @@
 static u_char end_mfs_root[] __unused = "MFS Filesystem had better STOP here";
 #endif
 
-static g_init_t md_drvinit;
 
 static int     mdrootready;
 static int     mdunits;
 static dev_t   status_dev = 0;
 
+
 static d_ioctl_t mdctlioctl;
+static g_init_t md_drvinit;
+static g_fini_t md_drvfini;
+static g_ctl_destroy_geom_t md_destroy_geom;
 
 static struct cdevsw mdctl_cdevsw = {
        .d_ioctl =      mdctlioctl,
@@ -121,6 +124,14 @@
 };
 
 
+struct g_class g_md_class = {
+       .name = "MD",
+       .init = md_drvinit,
+       .fini = md_drvfini,
+       .destroy_geom = md_destroy_geom,
+};
+
+
 static LIST_HEAD(, md_s) md_softc_list = LIST_HEAD_INITIALIZER(&md_softc_list);
 
 #define NINDIR (PAGE_SIZE / sizeof(uintptr_t))
@@ -168,7 +179,14 @@
        vm_object_t object;
 };
 
-static int mddestroy(struct md_s *sc, struct thread *td);
+struct md_tmp {
+       int     unit;
+       int     error;
+};
+
+
+static void mddestroy(struct md_s *sc);
+
 
 static struct indir *
 new_indir(u_int shift)
@@ -178,8 +196,8 @@
        ip = malloc(sizeof *ip, M_MD, M_NOWAIT | M_ZERO);
        if (ip == NULL)
                return (NULL);
-       ip->array = malloc(sizeof(uintptr_t) * NINDIR,
-           M_MDSECT, M_NOWAIT | M_ZERO);
+       ip->array = malloc(sizeof(uintptr_t) * NINDIR, M_MDSECT,
+           M_NOWAIT | M_ZERO);
        if (ip->array == NULL) {
                free(ip, M_MD);
                return (NULL);
@@ -240,8 +258,8 @@
         * too much space for ip->array in here.
         */
        ip = malloc(sizeof *ip, M_MD, M_WAITOK | M_ZERO);
-       ip->array = malloc(sizeof(uintptr_t) * NINDIR,
-           M_MDSECT, M_WAITOK | M_ZERO);
+       ip->array = malloc(sizeof(uintptr_t) * NINDIR, M_MDSECT,
+           M_WAITOK | M_ZERO);
        ip->total = NINDIR;
        ip->shift = layer * nshift;
        return (ip);
@@ -292,7 +310,7 @@
        cip = ip;
        for (;;) {
                lip[li++] = cip;
-               if (cip->shift) {
+               if (cip->shift > 0) {
                        idx = (offset >> cip->shift) & NMASK;
                        up = cip->array[idx];
                        if (up != 0) {
@@ -335,12 +353,6 @@
        return (0);
 }
 
-
-struct g_class g_md_class = {
-       .name = "MD",
-       .init = md_drvinit,
-};
-
 static int
 g_md_access(struct g_provider *pp, int r, int w, int e)
 {
@@ -352,11 +364,10 @@
        r += pp->acr;
        w += pp->acw;
        e += pp->ace;
-       if ((pp->acr + pp->acw + pp->ace) == 0 && (r + w + e) > 0) {
+       if ((pp->acr + pp->acw + pp->ace) == 0 && (r + w + e) > 0)
                sc->opencount = 1;
-       } else if ((pp->acr + pp->acw + pp->ace) > 0 && (r + w + e) == 0) {
+       else if ((pp->acr + pp->acw + pp->ace) > 0 && (r + w + e) == 0)
                sc->opencount = 0;
-       }
        return (0);
 }
 
@@ -376,9 +387,6 @@
        wakeup(sc);
 }
 
-DECLARE_GEOM_CLASS(g_md_class, g_md);
-
-
 static int
 mdstart_malloc(struct md_s *sc, struct bio *bp)
 {
@@ -391,7 +399,7 @@
        secno = bp->bio_pblkno;
        dst = bp->bio_data;
        error = 0;
-       while (nsec--) {
+       while (nsec-- > 0) {
                osp = s_read(sc->indir, secno);
                if (bp->bio_cmd == BIO_DELETE) {
                        if (osp != 0)
@@ -406,7 +414,7 @@
                                bcopy((void *)osp, dst, sc->secsize);
                        osp = 0;
                } else if (bp->bio_cmd == BIO_WRITE) {
-                       if (sc->flags & MD_COMPRESS) {
+                       if ((sc->flags & MD_COMPRESS) != 0) {
                                uc = dst[0];
                                for (i = 1; i < sc->secsize; i++)
                                        if (dst[i] != uc)
@@ -420,8 +428,8 @@
                                        error = s_write(sc->indir, secno, uc);
                        } else {
                                if (osp <= 255) {
-                                       sp = (uintptr_t) uma_zalloc(
-                                           sc->uma, M_NOWAIT);
+                                       sp = (uintptr_t)uma_zalloc(sc->uma,
+                                           M_NOWAIT);
                                        if (sp == 0) {
                                                error = ENOSPC;
                                                break;
@@ -438,7 +446,7 @@
                }
                if (osp > 255)
                        uma_zfree(sc->uma, (void*)osp);
-               if (error)
+               if (error != 0)
                        break;
                secno++;
                dst += sc->secsize;
@@ -452,10 +460,13 @@
 {
 
        if (bp->bio_cmd == BIO_DELETE) {
+               /* Nothing here. */
        } else if (bp->bio_cmd == BIO_READ) {
-               bcopy(sc->pl_ptr + (bp->bio_pblkno << DEV_BSHIFT), bp->bio_data, 
bp->bio_bcount);
+               bcopy(sc->pl_ptr + (bp->bio_pblkno << DEV_BSHIFT), bp->bio_data,
+                   bp->bio_bcount);
        } else {
-               bcopy(bp->bio_data, sc->pl_ptr + (bp->bio_pblkno << DEV_BSHIFT), 
bp->bio_bcount);
+               bcopy(bp->bio_data, sc->pl_ptr + (bp->bio_pblkno << DEV_BSHIFT),
+                   bp->bio_bcount);
        }
        bp->bio_resid = 0;
        return (0);
@@ -485,9 +496,9 @@
        auio.uio_iovcnt = 1;
        auio.uio_offset = (vm_ooffset_t)bp->bio_pblkno * sc->secsize;
        auio.uio_segflg = UIO_SYSSPACE;
-       if(bp->bio_cmd == BIO_READ)
+       if (bp->bio_cmd == BIO_READ)
                auio.uio_rw = UIO_READ;
-       else if(bp->bio_cmd == BIO_WRITE)
+       else if (bp->bio_cmd == BIO_WRITE)
                auio.uio_rw = UIO_WRITE;
        else
                panic("wrong BIO_OP in mdstart_vnode");
@@ -517,62 +528,57 @@
 static int
 mdstart_swap(struct md_s *sc, struct bio *bp)
 {
-       {
-               int i, o, rv;
-               vm_page_t m;
-               u_char *p;
-               vm_offset_t kva;
-
-               p = bp->bio_data;
-               o = bp->bio_offset / sc->secsize;
-               mtx_lock(&Giant);
-               kva = kmem_alloc_nofault(kernel_map, sc->secsize);
-               
-               VM_OBJECT_LOCK(sc->object);
-               vm_object_pip_add(sc->object, 1);
-               for (i = 0; i < bp->bio_length / sc->secsize; i++) {
-                       m = vm_page_grab(sc->object, i + o,
-                           VM_ALLOC_NORMAL|VM_ALLOC_RETRY);
-                       pmap_qenter(kva, &m, 1);
-                       if (bp->bio_cmd == BIO_READ) {
-                               if (m->valid != VM_PAGE_BITS_ALL) {
-                                       rv = vm_pager_get_pages(sc->object,
-                                           &m, 1, 0);
-                               }
-                               bcopy((void *)kva, p, sc->secsize);
-                       } else if (bp->bio_cmd == BIO_WRITE) {
-                               bcopy(p, (void *)kva, sc->secsize);
-                               m->valid = VM_PAGE_BITS_ALL;
+       int i, o, rv;
+       vm_page_t m;
+       u_char *p;
+       vm_offset_t kva;
+
+       p = bp->bio_data;
+       o = bp->bio_offset / sc->secsize;
+       mtx_lock(&Giant);
+       kva = kmem_alloc_nofault(kernel_map, sc->secsize);
+
+       VM_OBJECT_LOCK(sc->object);
+       vm_object_pip_add(sc->object, 1);
+       for (i = 0; i < bp->bio_length / sc->secsize; i++) {
+               m = vm_page_grab(sc->object, i + o,
+                   VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
+               pmap_qenter(kva, &m, 1);
+               if (bp->bio_cmd == BIO_READ) {
+                       if (m->valid != VM_PAGE_BITS_ALL)
+                               rv = vm_pager_get_pages(sc->object, &m, 1, 0);
+                       bcopy((void *)kva, p, sc->secsize);
+               } else if (bp->bio_cmd == BIO_WRITE) {
+                       bcopy(p, (void *)kva, sc->secsize);
+                       m->valid = VM_PAGE_BITS_ALL;
 #if 0
-                       } else if (bp->bio_cmd == BIO_DELETE) {
-                               bzero((void *)kva, sc->secsize);
-                               vm_page_dirty(m);
-                               m->valid = VM_PAGE_BITS_ALL;
+               } else if (bp->bio_cmd == BIO_DELETE) {
+                       bzero((void *)kva, sc->secsize);
+                       vm_page_dirty(m);
+                       m->valid = VM_PAGE_BITS_ALL;
 #endif
-                       } 
-                       pmap_qremove(kva, 1);
-                       vm_page_lock_queues();
-                       vm_page_wakeup(m);
-                       vm_page_activate(m);
-                       if (bp->bio_cmd == BIO_WRITE) {
-                               vm_page_dirty(m);
-                       }
-                       vm_page_unlock_queues();
-                       p += sc->secsize;
+               } 
+               pmap_qremove(kva, 1);
+               vm_page_lock_queues();
+               vm_page_wakeup(m);
+               vm_page_activate(m);
+               if (bp->bio_cmd == BIO_WRITE)
+                       vm_page_dirty(m);
+               vm_page_unlock_queues();
+               p += sc->secsize;
 #if 0
 if (bootverbose || o < 17)
 printf("wire_count %d busy %d flags %x hold_count %d act_count %d queue %d valid %d 
dirty %d @ %d\n",
     m->wire_count, m->busy, 
     m->flags, m->hold_count, m->act_count, m->queue, m->valid, m->dirty, o + i);
 #endif
-               }
-               vm_object_pip_subtract(sc->object, 1);
-               vm_object_set_writeable_dirty(sc->object);
-               VM_OBJECT_UNLOCK(sc->object);
-               kmem_free(kernel_map, kva, sc->secsize);
-               mtx_unlock(&Giant);
-               return (0);
        }
+       vm_object_pip_subtract(sc->object, 1);
+       vm_object_set_writeable_dirty(sc->object);
+       VM_OBJECT_UNLOCK(sc->object);
+       kmem_free(kernel_map, kva, sc->secsize);
+       mtx_unlock(&Giant);
+       return (0);
 }
 
 static void
@@ -601,10 +607,10 @@
        for (;;) {
                mtx_lock(&sc->queue_mtx);
                bp = bioq_first(&sc->bio_queue);
-               if (bp)
+               if (bp != NULL)
                        bioq_remove(&sc->bio_queue, bp);
-               if (!bp) {
-                       if (sc->flags & MD_SHUTDOWN) {
+               else {
+                       if ((sc->flags & MD_SHUTDOWN) != 0) {
                                mtx_unlock(&sc->queue_mtx);
                                sc->procp = NULL;
                                wakeup(&sc->procp);
@@ -617,14 +623,17 @@
                }
                mtx_unlock(&sc->queue_mtx);
                if (bp->bio_cmd == BIO_GETATTR) {
-                       if (sc->fwsectors && sc->fwheads &&
-                           (g_handleattr_int(bp, "GEOM::fwsectors",
-                           sc->fwsectors) ||
-                           g_handleattr_int(bp, "GEOM::fwheads",
-                           sc->fwheads)))
-                               error = -1;
-                       else
-                               error = EOPNOTSUPP;
+                       if (sc->fwsectors > 0 && sc->fwheads > 0) {
+                               if (g_handleattr_int(bp, "GEOM::fwsectors",
+                                   sc->fwsectors)) {
+                                       continue;
+                               }
+                               if (g_handleattr_int(bp, "GEOM::fwheads",
+                                   sc->fwheads)) {
+                                       continue;
+                               }
+                       }
+                       error = EOPNOTSUPP;
                } else {
                        switch (sc->type) {
                        case MD_MALLOC:
@@ -640,15 +649,12 @@
                                error = mdstart_swap(sc, bp);
                                break;
                        default:
-                               panic("Impossible md(type)");
+                               panic("impossible md type (%d)", sc->type);
                                break;
                        }
                }
-
-               if (error != -1) {
-                       bp->bio_completed = bp->bio_length;
-                       g_io_deliver(bp, error);
-               }
+               bp->bio_completed = bp->bio_length;
+               g_io_deliver(bp, error);
        }
 }
 
@@ -689,7 +695,7 @@
        mtx_init(&sc->queue_mtx, "md bio queue", NULL, MTX_DEF);
        sprintf(sc->name, "md%d", unit);
        error = kthread_create(md_kthread, sc, &sc->procp, 0, 0,"%s", sc->name);
-       if (error) {
+       if (error != 0) {
                free(sc, M_MD);
                return (NULL);
        }
@@ -701,7 +707,6 @@
 static void
 mdinit(struct md_s *sc)
 {
-
        struct g_geom *gp;
        struct g_provider *pp;
 
@@ -768,14 +773,14 @@
        error = 0;
        if (mdio->md_size == 0)
                return (EINVAL);
-       if (mdio->md_options & ~(MD_AUTOUNIT | MD_COMPRESS | MD_RESERVE))
+       if ((mdio->md_options & ~(MD_AUTOUNIT | MD_COMPRESS | MD_RESERVE)) != 0)
                return (EINVAL);
        if (mdio->md_secsize != 0 && !powerof2(mdio->md_secsize))
                return (EINVAL);
        /* Compression doesn't make sense if we have reserved space */
-       if (mdio->md_options & MD_RESERVE)
+       if ((mdio->md_options & MD_RESERVE) != 0)
                mdio->md_options &= ~MD_COMPRESS;
-       if (mdio->md_options & MD_AUTOUNIT) {
+       if ((mdio->md_options & MD_AUTOUNIT) != 0) {
                sc = mdnew(-1);
                if (sc == NULL)
                        return (ENOMEM);
@@ -800,23 +805,23 @@
        sc->indir = dimension(sc->nsect);
        sc->uma = uma_zcreate(sc->name, sc->secsize,
            NULL, NULL, NULL, NULL, 0x1ff, 0);
-       if (mdio->md_options & MD_RESERVE) {
+       if ((mdio->md_options & MD_RESERVE) != 0) {
                for (u = 0; u < sc->nsect; u++) {
-                       sp = (uintptr_t) uma_zalloc(sc->uma, M_NOWAIT | M_ZERO);
+                       sp = (uintptr_t)uma_zalloc(sc->uma, M_NOWAIT | M_ZERO);
                        if (sp != 0)
                                error = s_write(sc->indir, u, sp);
                        else
                                error = ENOMEM;
-                       if (error)
+                       if (error != 0)
                                break;
                }
        }
-       if (error)  {
-               mddestroy(sc, NULL);
+       if (error != 0)  {
+               mddestroy(sc);
                return (error);
        }
        mdinit(sc);
-       if (!(mdio->md_options & MD_RESERVE))
+       if ((mdio->md_options & MD_RESERVE) == 0)
                sc->pp->flags |= G_PF_CANDELETE;
        return (0);
 }
@@ -840,7 +845,7 @@
         * Horrible kludge to establish credentials for NFS  XXX.
         */
 
-       if (sc->vnode) {
+       if (sc->vnode != NULL) {
                struct uio auio;
                struct iovec aiov;
 
@@ -874,23 +879,26 @@
        flags = FREAD|FWRITE;
        NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, mdio->md_file, td);
        error = vn_open(&nd, &flags, 0, -1);
-       if (error) {
+       if (error != 0) {
                if (error != EACCES && error != EPERM && error != EROFS)
                        return (error);
                flags &= ~FWRITE;
                NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, mdio->md_file, td);
                error = vn_open(&nd, &flags, 0, -1);
-               if (error)
+               if (error != 0)
                        return (error);
        }
        NDFREE(&nd, NDF_ONLY_PNBUF);
-       if (nd.ni_vp->v_type != VREG ||
-           (error = VOP_GETATTR(nd.ni_vp, &vattr, td->td_ucred, td))) {
-               VOP_UNLOCK(nd.ni_vp, 0, td);
-               (void) vn_close(nd.ni_vp, flags, td->td_ucred, td);
-               return (error ? error : EINVAL);
-       }
        VOP_UNLOCK(nd.ni_vp, 0, td);
+       if (nd.ni_vp->v_type != VREG) {
+               vn_close(nd.ni_vp, flags, td->td_ucred, td);
+               return (EINVAL);
+       }
+       error = VOP_GETATTR(nd.ni_vp, &vattr, td->td_ucred, td);
+       if (error != 0) {
+               vn_close(nd.ni_vp, flags, td->td_ucred, td);
+               return (error);
+       }
 
        if (mdio->md_options & MD_AUTOUNIT) {
                sc = mdnew(-1);
@@ -899,13 +907,13 @@
                sc = mdnew(mdio->md_unit);
        }
        if (sc == NULL) {
-               (void) vn_close(nd.ni_vp, flags, td->td_ucred, td);
+               vn_close(nd.ni_vp, flags, td->td_ucred, td);
                return (EBUSY);
        }
 
        sc->type = MD_VNODE;
        sc->flags = mdio->md_options & MD_FORCE;
-       if (!(flags & FWRITE))
+       if ((flags & FWRITE) == 0)
                sc->flags |= MD_READONLY;
        sc->secsize = DEV_BSIZE;
        sc->vnode = nd.ni_vp;
@@ -913,17 +921,17 @@
        /*
         * If the size is specified, override the file attributes.
         */
-       if (mdio->md_size)
+       if (mdio->md_size > 0)
                sc->nsect = mdio->md_size;
        else
                sc->nsect = vattr.va_size / sc->secsize; /* XXX: round up ? */
        if (sc->nsect == 0) {
-               mddestroy(sc, td);
+               mddestroy(sc);
                return (EINVAL);
        }
        error = mdsetcred(sc, td->td_ucred);
-       if (error) {
-               mddestroy(sc, td);
+       if (error != 0) {
+               mddestroy(sc);
                return (error);
        }
        mdinit(sc);
@@ -931,23 +939,15 @@
 }
 
 static void
-md_zapit(void *p, int cancel)
-{
-       if (cancel)
-               return;
-       g_wither_geom(p, ENXIO);
-}
-
-static int
-mddestroy(struct md_s *sc, struct thread *td)
+mddestroy(struct md_s *sc)
 {
 
        GIANT_REQUIRED;
 
        mtx_destroy(&sc->queue_mtx);
-       if (sc->gp) {
+       if (sc->gp != NULL) {
                sc->gp->softc = NULL;
-               g_waitfor_event(md_zapit, sc->gp, M_WAITOK, sc->gp, NULL);
+               g_wither_geom(sc->gp, ENXIO);
                sc->gp = NULL;
                sc->pp = NULL;
        }
@@ -955,24 +955,27 @@
        wakeup(sc);
        while (sc->procp != NULL)
                tsleep(&sc->procp, PRIBIO, "mddestroy", hz / 10);
-       if (sc->vnode != NULL)
-               (void)vn_close(sc->vnode, sc->flags & MD_READONLY ?
-                   FREAD : (FREAD|FWRITE), sc->cred, td);
+       if (sc->vnode != NULL) {
+               int flags;
+
+               flags = FREAD;
+               if ((sc->flags & MD_READONLY) == 0)
+                       flags |= FWRITE;
+               vn_close(sc->vnode, flags, sc->cred, curthread);
+       }
        if (sc->cred != NULL)
                crfree(sc->cred);
-       if (sc->object != NULL) {
+       if (sc->object != NULL)
                vm_object_deallocate(sc->object);
-       }
-       if (sc->indir)
+       if (sc->indir != NULL)
                destroy_indir(sc, sc->indir);
-       if (sc->uma)
+       if (sc->uma != NULL)
                uma_zdestroy(sc->uma);
 
        /* XXX: LOCK(unique unit numbers) */
        LIST_REMOVE(sc, list);
        /* XXX: UNLOCK(unique unit numbers) */
        free(sc, M_MD);
-       return (0);
 }
 
 static int
@@ -1000,7 +1003,7 @@
         */
 
        if (mdio->md_size == 0) {
-               mddestroy(sc, td);
+               mddestroy(sc);
                return (EDOM);
        }
 
@@ -1015,45 +1018,58 @@
 
        sc->secsize = PAGE_SIZE;
        sc->nsect = mdio->md_size / (PAGE_SIZE / DEV_BSIZE);
-       sc->object = vm_pager_allocate(OBJT_SWAP, NULL, sc->secsize * 
(vm_offset_t)sc->nsect, VM_PROT_DEFAULT, 0);
+       sc->object = vm_pager_allocate(OBJT_SWAP, NULL,
+           sc->secsize * (vm_offset_t)sc->nsect, VM_PROT_DEFAULT, 0);
        sc->flags = mdio->md_options & MD_FORCE;
-       if (mdio->md_options & MD_RESERVE) {
+       if ((mdio->md_options & MD_RESERVE) != 0) {
                if (swap_pager_reserve(sc->object, 0, sc->nsect) < 0) {
                        vm_object_deallocate(sc->object);
                        sc->object = NULL;
-                       mddestroy(sc, td);
+                       mddestroy(sc);
                        return (EDOM);
                }
        }
        error = mdsetcred(sc, td->td_ucred);
-       if (error) {
-               mddestroy(sc, td);
+       if (error != 0) {
+               mddestroy(sc);
                return (error);
        }
        mdinit(sc);
-       if (!(mdio->md_options & MD_RESERVE))
+       if ((mdio->md_options & MD_RESERVE) == 0)
                sc->pp->flags |= G_PF_CANDELETE;
        return (0);
 }
 
-static int
-mddetach(int unit, struct thread *td)
+static void
+mddetach(void *p, int cancel)
 {
        struct md_s *sc;
+       struct md_tmp *tmp;
 
-       sc = mdfind(unit);
-       if (sc == NULL)
-               return (ENOENT);
-       if (sc->opencount != 0 && !(sc->flags & MD_FORCE))
-               return (EBUSY);
+       if (cancel != 0)
+               return;
+       tmp = p;
+
+       sc = mdfind(tmp->unit);
+       if (sc == NULL) {
+               tmp->error = ENOENT;
+               return;
+       }
+       if (sc->opencount != 0 && (sc->flags & MD_FORCE) == 0) {
+               tmp->error = EBUSY;
+               return;
+       }
        switch(sc->type) {
        case MD_VNODE:
        case MD_SWAP:
        case MD_MALLOC:
        case MD_PRELOAD:
-               return (mddestroy(sc, td));
+               tmp->error = 0;
+               mddestroy(sc);
+               return;
        default:
-               return (EOPNOTSUPP);
+               tmp->error = EOPNOTSUPP;
+               return;
        }
 }
 
@@ -1064,9 +1080,10 @@
        struct md_s *sc;
        int i;
 
-       if (md_debug)
-               printf("mdctlioctl(%s %lx %p %x %p)\n",
-                       devtoname(dev), cmd, addr, flags, td);
+       if (md_debug > 0) {
+               printf("mdctlioctl(%s %lx %p %x %p)\n", devtoname(dev), cmd,
+                   addr, flags, td);
+       }
 
        /*
         * We assert the version number in the individual ioctl
@@ -1092,13 +1109,25 @@
                default:
                        return (EINVAL);
                }
-       case MDIOCDETACH:
+       case MDIOCDETACH: {
+               struct md_tmp *tmp;
+               int error;
+
                if (mdio->md_version != MDIOVERSION)
                        return (EINVAL);
                if (mdio->md_file != NULL || mdio->md_size != 0 ||
-                   mdio->md_options != 0)
+                   mdio->md_options != 0) {
                        return (EINVAL);
-               return (mddetach(mdio->md_unit, td));
+               }
+
+               tmp = malloc(sizeof(*tmp), M_TEMP, M_WAITOK | M_ZERO);
+               tmp->unit = mdio->md_unit;
+               g_waitfor_event(mddetach, tmp, M_WAITOK, tmp, NULL);
+               error = tmp->error;
+               free(tmp, M_TEMP);
+
+               return (error);
+       }
        case MDIOCQUERY:
                if (mdio->md_version != MDIOVERSION)
                        return (EINVAL);
@@ -1162,7 +1191,6 @@
 static void
 md_drvinit(struct g_class *mp __unused)
 {
-
        caddr_t mod;
        caddr_t c;
        u_char *ptr, *name, *type;
@@ -1180,8 +1208,10 @@
                        continue;
                if (type == NULL)
                        continue;
-               if (strcmp(type, "md_image") && strcmp(type, "mfs_root"))
+               if (strcmp(type, "md_image") != 0 &&
+                   strcmp(type, "mfs_root") != 0) {
                        continue;
+               }
                c = preload_search_info(mod, MODINFO_ADDR);
                ptr = *(u_char **)c;
                c = preload_search_info(mod, MODINFO_SIZE);
@@ -1195,39 +1225,37 @@
        g_topology_lock();
 }
 
+static void
+md_drvfini(struct g_class *mp __unused)
+{
+
+       KASSERT(LIST_EMPTY(&md_softc_list), ("device list isn't empty"));
+
+       if (status_dev)
+               destroy_dev(status_dev);
+       status_dev = 0;
+}
+
 static int
-md_modevent(module_t mod, int type, void *data)
+md_destroy_geom(struct gctl_req *req, struct g_class *mp, struct g_geom *gp)
 {
-       int error;
        struct md_s *sc;
+       struct md_tmp tmp;
 
-       switch (type) {
-       case MOD_LOAD:
-               break;
-       case MOD_UNLOAD:
-               LIST_FOREACH(sc, &md_softc_list, list) {
-                       error = mddetach(sc->unit, curthread);
-                       if (error != 0)
-                               return (error);
-               }
-               if (status_dev)
-                       destroy_dev(status_dev);
-               status_dev = 0;
-               break;
-       default:
-               break;
-       }
-       return (0);
+       g_topology_assert();
+       sc = gp->softc;
+
+       tmp.unit = sc->unit;
+       tmp.error = 0;
+       mtx_lock(&Giant);
+       mddetach(&tmp, 0);
+       mtx_unlock(&Giant);
+
+       return (tmp.error);
 }
 
-static moduledata_t md_mod = {
-       MD_NAME,
-       md_modevent,
-       NULL
-};
-DECLARE_MODULE(md, md_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
+DECLARE_GEOM_CLASS(g_md_class, md);
 MODULE_VERSION(md, MD_MODVER);
-
 
 #ifdef MD_ROOT
 static void

Attachment: pgp00000.pgp
Description: PGP signature

Reply via email to