Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 Jan 2004 16:58:42 +0100
From:      Pawel Jakub Dawidek <nick@garage.freebsd.pl>
To:        freebsd-hackers@freebsd.org
Cc:        phk@freebsd.org
Subject:   MD(4) cleanups and unload lesson.
Message-ID:  <20040111155842.GB74246@garage.freebsd.pl>

next in thread | raw e-mail | index | archive | help

--veXX9dWIonWZEC6h
Content-Type: multipart/mixed; boundary="w7PDEPdKQumQfZlR"
Content-Disposition: inline


--w7PDEPdKQumQfZlR
Content-Type: text/plain; charset=iso-8859-2
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

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

--=20
Pawel Jakub Dawidek                       pawel@dawidek.net
UNIX Systems Programmer/Administrator     http://garage.freebsd.pl
Am I Evil? Yes, I Am!                     http://cerber.sourceforge.net

--w7PDEPdKQumQfZlR
Content-Type: text/plain; charset=iso-8859-2
Content-Disposition: attachment; filename="md.c.patch"
Content-Transfer-Encoding: quoted-printable

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");
=20
-static int md_debug;
+static int md_debug =3D 0;
 SYSCTL_INT(_debug, OID_AUTO, mddebug, CTLFLAG_RW, &md_debug, 0, "");
=20
 #if defined(MD_ROOT) && defined(MD_ROOT_SIZE)
@@ -107,13 +107,16 @@
 static u_char end_mfs_root[] __unused =3D "MFS Filesystem had better STOP =
here";
 #endif
=20
-static g_init_t md_drvinit;
=20
 static int	mdrootready;
 static int	mdunits;
 static dev_t	status_dev =3D 0;
=20
+
 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;
=20
 static struct cdevsw mdctl_cdevsw =3D {
 	.d_ioctl =3D	mdctlioctl,
@@ -121,6 +124,14 @@
 };
=20
=20
+struct g_class g_md_class =3D {
+	.name =3D "MD",
+	.init =3D md_drvinit,
+	.fini =3D md_drvfini,
+	.destroy_geom =3D md_destroy_geom,
+};
+
+
 static LIST_HEAD(, md_s) md_softc_list =3D LIST_HEAD_INITIALIZER(&md_softc=
_list);
=20
 #define NINDIR	(PAGE_SIZE / sizeof(uintptr_t))
@@ -168,7 +179,14 @@
 	vm_object_t object;
 };
=20
-static int mddestroy(struct md_s *sc, struct thread *td);
+struct md_tmp {
+	int	unit;
+	int	error;
+};
+
+
+static void mddestroy(struct md_s *sc);
+
=20
 static struct indir *
 new_indir(u_int shift)
@@ -178,8 +196,8 @@
 	ip =3D malloc(sizeof *ip, M_MD, M_NOWAIT | M_ZERO);
 	if (ip =3D=3D NULL)
 		return (NULL);
-	ip->array =3D malloc(sizeof(uintptr_t) * NINDIR,
-	    M_MDSECT, M_NOWAIT | M_ZERO);
+	ip->array =3D malloc(sizeof(uintptr_t) * NINDIR, M_MDSECT,
+	    M_NOWAIT | M_ZERO);
 	if (ip->array =3D=3D NULL) {
 		free(ip, M_MD);
 		return (NULL);
@@ -240,8 +258,8 @@
 	 * too much space for ip->array in here.
 	 */
 	ip =3D malloc(sizeof *ip, M_MD, M_WAITOK | M_ZERO);
-	ip->array =3D malloc(sizeof(uintptr_t) * NINDIR,
-	    M_MDSECT, M_WAITOK | M_ZERO);
+	ip->array =3D malloc(sizeof(uintptr_t) * NINDIR, M_MDSECT,
+	    M_WAITOK | M_ZERO);
 	ip->total =3D NINDIR;
 	ip->shift =3D layer * nshift;
 	return (ip);
@@ -292,7 +310,7 @@
 	cip =3D ip;
 	for (;;) {
 		lip[li++] =3D cip;
-		if (cip->shift) {
+		if (cip->shift > 0) {
 			idx =3D (offset >> cip->shift) & NMASK;
 			up =3D cip->array[idx];
 			if (up !=3D 0) {
@@ -335,12 +353,6 @@
 	return (0);
 }
=20
-
-struct g_class g_md_class =3D {
-	.name =3D "MD",
-	.init =3D md_drvinit,
-};
-
 static int
 g_md_access(struct g_provider *pp, int r, int w, int e)
 {
@@ -352,11 +364,10 @@
 	r +=3D pp->acr;
 	w +=3D pp->acw;
 	e +=3D pp->ace;
-	if ((pp->acr + pp->acw + pp->ace) =3D=3D 0 && (r + w + e) > 0) {
+	if ((pp->acr + pp->acw + pp->ace) =3D=3D 0 && (r + w + e) > 0)
 		sc->opencount =3D 1;
-	} else if ((pp->acr + pp->acw + pp->ace) > 0 && (r + w + e) =3D=3D 0) {
+	else if ((pp->acr + pp->acw + pp->ace) > 0 && (r + w + e) =3D=3D 0)
 		sc->opencount =3D 0;
-	}
 	return (0);
 }
=20
@@ -376,9 +387,6 @@
 	wakeup(sc);
 }
=20
-DECLARE_GEOM_CLASS(g_md_class, g_md);
-
-
 static int
 mdstart_malloc(struct md_s *sc, struct bio *bp)
 {
@@ -391,7 +399,7 @@
 	secno =3D bp->bio_pblkno;
 	dst =3D bp->bio_data;
 	error =3D 0;
-	while (nsec--) {
+	while (nsec-- > 0) {
 		osp =3D s_read(sc->indir, secno);
 		if (bp->bio_cmd =3D=3D BIO_DELETE) {
 			if (osp !=3D 0)
@@ -406,7 +414,7 @@
 				bcopy((void *)osp, dst, sc->secsize);
 			osp =3D 0;
 		} else if (bp->bio_cmd =3D=3D BIO_WRITE) {
-			if (sc->flags & MD_COMPRESS) {
+			if ((sc->flags & MD_COMPRESS) !=3D 0) {
 				uc =3D dst[0];
 				for (i =3D 1; i < sc->secsize; i++)
 					if (dst[i] !=3D uc)
@@ -420,8 +428,8 @@
 					error =3D s_write(sc->indir, secno, uc);
 			} else {
 				if (osp <=3D 255) {
-					sp =3D (uintptr_t) uma_zalloc(
-					    sc->uma, M_NOWAIT);
+					sp =3D (uintptr_t)uma_zalloc(sc->uma,
+					    M_NOWAIT);
 					if (sp =3D=3D 0) {
 						error =3D ENOSPC;
 						break;
@@ -438,7 +446,7 @@
 		}
 		if (osp > 255)
 			uma_zfree(sc->uma, (void*)osp);
-		if (error)
+		if (error !=3D 0)
 			break;
 		secno++;
 		dst +=3D sc->secsize;
@@ -452,10 +460,13 @@
 {
=20
 	if (bp->bio_cmd =3D=3D BIO_DELETE) {
+		/* Nothing here. */
 	} else if (bp->bio_cmd =3D=3D 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 =3D 0;
 	return (0);
@@ -485,9 +496,9 @@
 	auio.uio_iovcnt =3D 1;
 	auio.uio_offset =3D (vm_ooffset_t)bp->bio_pblkno * sc->secsize;
 	auio.uio_segflg =3D UIO_SYSSPACE;
-	if(bp->bio_cmd =3D=3D BIO_READ)
+	if (bp->bio_cmd =3D=3D BIO_READ)
 		auio.uio_rw =3D UIO_READ;
-	else if(bp->bio_cmd =3D=3D BIO_WRITE)
+	else if (bp->bio_cmd =3D=3D BIO_WRITE)
 		auio.uio_rw =3D 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 =3D bp->bio_data;
-		o =3D bp->bio_offset / sc->secsize;
-		mtx_lock(&Giant);
-		kva =3D kmem_alloc_nofault(kernel_map, sc->secsize);
-	=09
-		VM_OBJECT_LOCK(sc->object);
-		vm_object_pip_add(sc->object, 1);
-		for (i =3D 0; i < bp->bio_length / sc->secsize; i++) {
-			m =3D vm_page_grab(sc->object, i + o,
-			    VM_ALLOC_NORMAL|VM_ALLOC_RETRY);
-			pmap_qenter(kva, &m, 1);
-			if (bp->bio_cmd =3D=3D BIO_READ) {
-				if (m->valid !=3D VM_PAGE_BITS_ALL) {
-					rv =3D vm_pager_get_pages(sc->object,
-					    &m, 1, 0);
-				}
-				bcopy((void *)kva, p, sc->secsize);
-			} else if (bp->bio_cmd =3D=3D BIO_WRITE) {
-				bcopy(p, (void *)kva, sc->secsize);
-				m->valid =3D VM_PAGE_BITS_ALL;
+	int i, o, rv;
+	vm_page_t m;
+	u_char *p;
+	vm_offset_t kva;
+
+	p =3D bp->bio_data;
+	o =3D bp->bio_offset / sc->secsize;
+	mtx_lock(&Giant);
+	kva =3D kmem_alloc_nofault(kernel_map, sc->secsize);
+
+	VM_OBJECT_LOCK(sc->object);
+	vm_object_pip_add(sc->object, 1);
+	for (i =3D 0; i < bp->bio_length / sc->secsize; i++) {
+		m =3D vm_page_grab(sc->object, i + o,
+		    VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
+		pmap_qenter(kva, &m, 1);
+		if (bp->bio_cmd =3D=3D BIO_READ) {
+			if (m->valid !=3D VM_PAGE_BITS_ALL)
+				rv =3D vm_pager_get_pages(sc->object, &m, 1, 0);
+			bcopy((void *)kva, p, sc->secsize);
+		} else if (bp->bio_cmd =3D=3D BIO_WRITE) {
+			bcopy(p, (void *)kva, sc->secsize);
+			m->valid =3D VM_PAGE_BITS_ALL;
 #if 0
-			} else if (bp->bio_cmd =3D=3D BIO_DELETE) {
-				bzero((void *)kva, sc->secsize);
-				vm_page_dirty(m);
-				m->valid =3D VM_PAGE_BITS_ALL;
+		} else if (bp->bio_cmd =3D=3D BIO_DELETE) {
+			bzero((void *)kva, sc->secsize);
+			vm_page_dirty(m);
+			m->valid =3D VM_PAGE_BITS_ALL;
 #endif
-			}=20
-			pmap_qremove(kva, 1);
-			vm_page_lock_queues();
-			vm_page_wakeup(m);
-			vm_page_activate(m);
-			if (bp->bio_cmd =3D=3D BIO_WRITE) {
-				vm_page_dirty(m);
-			}
-			vm_page_unlock_queues();
-			p +=3D sc->secsize;
+		}=20
+		pmap_qremove(kva, 1);
+		vm_page_lock_queues();
+		vm_page_wakeup(m);
+		vm_page_activate(m);
+		if (bp->bio_cmd =3D=3D BIO_WRITE)
+			vm_page_dirty(m);
+		vm_page_unlock_queues();
+		p +=3D 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,=20
     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);
 }
=20
 static void
@@ -601,10 +607,10 @@
 	for (;;) {
 		mtx_lock(&sc->queue_mtx);
 		bp =3D bioq_first(&sc->bio_queue);
-		if (bp)
+		if (bp !=3D NULL)
 			bioq_remove(&sc->bio_queue, bp);
-		if (!bp) {
-			if (sc->flags & MD_SHUTDOWN) {
+		else {
+			if ((sc->flags & MD_SHUTDOWN) !=3D 0) {
 				mtx_unlock(&sc->queue_mtx);
 				sc->procp =3D NULL;
 				wakeup(&sc->procp);
@@ -617,14 +623,17 @@
 		}
 		mtx_unlock(&sc->queue_mtx);
 		if (bp->bio_cmd =3D=3D BIO_GETATTR) {
-			if (sc->fwsectors && sc->fwheads &&
-			    (g_handleattr_int(bp, "GEOM::fwsectors",
-			    sc->fwsectors) ||
-			    g_handleattr_int(bp, "GEOM::fwheads",
-			    sc->fwheads)))
-				error =3D -1;
-			else
-				error =3D 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 =3D EOPNOTSUPP;
 		} else {
 			switch (sc->type) {
 			case MD_MALLOC:
@@ -640,15 +649,12 @@
 				error =3D mdstart_swap(sc, bp);
 				break;
 			default:
-				panic("Impossible md(type)");
+				panic("impossible md type (%d)", sc->type);
 				break;
 			}
 		}
-
-		if (error !=3D -1) {
-			bp->bio_completed =3D bp->bio_length;
-			g_io_deliver(bp, error);
-		}
+		bp->bio_completed =3D bp->bio_length;
+		g_io_deliver(bp, error);
 	}
 }
=20
@@ -689,7 +695,7 @@
 	mtx_init(&sc->queue_mtx, "md bio queue", NULL, MTX_DEF);
 	sprintf(sc->name, "md%d", unit);
 	error =3D kthread_create(md_kthread, sc, &sc->procp, 0, 0,"%s", sc->name);
-	if (error) {
+	if (error !=3D 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;
=20
@@ -768,14 +773,14 @@
 	error =3D 0;
 	if (mdio->md_size =3D=3D 0)
 		return (EINVAL);
-	if (mdio->md_options & ~(MD_AUTOUNIT | MD_COMPRESS | MD_RESERVE))
+	if ((mdio->md_options & ~(MD_AUTOUNIT | MD_COMPRESS | MD_RESERVE)) !=3D 0)
 		return (EINVAL);
 	if (mdio->md_secsize !=3D 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) !=3D 0)
 		mdio->md_options &=3D ~MD_COMPRESS;
-	if (mdio->md_options & MD_AUTOUNIT) {
+	if ((mdio->md_options & MD_AUTOUNIT) !=3D 0) {
 		sc =3D mdnew(-1);
 		if (sc =3D=3D NULL)
 			return (ENOMEM);
@@ -800,23 +805,23 @@
 	sc->indir =3D dimension(sc->nsect);
 	sc->uma =3D uma_zcreate(sc->name, sc->secsize,
 	    NULL, NULL, NULL, NULL, 0x1ff, 0);
-	if (mdio->md_options & MD_RESERVE) {
+	if ((mdio->md_options & MD_RESERVE) !=3D 0) {
 		for (u =3D 0; u < sc->nsect; u++) {
-			sp =3D (uintptr_t) uma_zalloc(sc->uma, M_NOWAIT | M_ZERO);
+			sp =3D (uintptr_t)uma_zalloc(sc->uma, M_NOWAIT | M_ZERO);
 			if (sp !=3D 0)
 				error =3D s_write(sc->indir, u, sp);
 			else
 				error =3D ENOMEM;
-			if (error)
+			if (error !=3D 0)
 				break;
 		}
 	}
-	if (error)  {
-		mddestroy(sc, NULL);
+	if (error !=3D 0)  {
+		mddestroy(sc);
 		return (error);
 	}
 	mdinit(sc);
-	if (!(mdio->md_options & MD_RESERVE))
+	if ((mdio->md_options & MD_RESERVE) =3D=3D 0)
 		sc->pp->flags |=3D G_PF_CANDELETE;
 	return (0);
 }
@@ -840,7 +845,7 @@
 	 * Horrible kludge to establish credentials for NFS  XXX.
 	 */
=20
-	if (sc->vnode) {
+	if (sc->vnode !=3D NULL) {
 		struct uio auio;
 		struct iovec aiov;
=20
@@ -874,23 +879,26 @@
 	flags =3D FREAD|FWRITE;
 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, mdio->md_file, td);
 	error =3D vn_open(&nd, &flags, 0, -1);
-	if (error) {
+	if (error !=3D 0) {
 		if (error !=3D EACCES && error !=3D EPERM && error !=3D EROFS)
 			return (error);
 		flags &=3D ~FWRITE;
 		NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, mdio->md_file, td);
 		error =3D vn_open(&nd, &flags, 0, -1);
-		if (error)
+		if (error !=3D 0)
 			return (error);
 	}
 	NDFREE(&nd, NDF_ONLY_PNBUF);
-	if (nd.ni_vp->v_type !=3D VREG ||
-	    (error =3D 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 !=3D VREG) {
+		vn_close(nd.ni_vp, flags, td->td_ucred, td);
+		return (EINVAL);
+	}
+	error =3D VOP_GETATTR(nd.ni_vp, &vattr, td->td_ucred, td);
+	if (error !=3D 0) {
+		vn_close(nd.ni_vp, flags, td->td_ucred, td);
+		return (error);
+	}
=20
 	if (mdio->md_options & MD_AUTOUNIT) {
 		sc =3D mdnew(-1);
@@ -899,13 +907,13 @@
 		sc =3D mdnew(mdio->md_unit);
 	}
 	if (sc =3D=3D NULL) {
-		(void) vn_close(nd.ni_vp, flags, td->td_ucred, td);
+		vn_close(nd.ni_vp, flags, td->td_ucred, td);
 		return (EBUSY);
 	}
=20
 	sc->type =3D MD_VNODE;
 	sc->flags =3D mdio->md_options & MD_FORCE;
-	if (!(flags & FWRITE))
+	if ((flags & FWRITE) =3D=3D 0)
 		sc->flags |=3D MD_READONLY;
 	sc->secsize =3D DEV_BSIZE;
 	sc->vnode =3D 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 =3D mdio->md_size;
 	else
 		sc->nsect =3D vattr.va_size / sc->secsize; /* XXX: round up ? */
 	if (sc->nsect =3D=3D 0) {
-		mddestroy(sc, td);
+		mddestroy(sc);
 		return (EINVAL);
 	}
 	error =3D mdsetcred(sc, td->td_ucred);
-	if (error) {
-		mddestroy(sc, td);
+	if (error !=3D 0) {
+		mddestroy(sc);
 		return (error);
 	}
 	mdinit(sc);
@@ -931,23 +939,15 @@
 }
=20
 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)
 {
=20
 	GIANT_REQUIRED;
=20
 	mtx_destroy(&sc->queue_mtx);
-	if (sc->gp) {
+	if (sc->gp !=3D NULL) {
 		sc->gp->softc =3D NULL;
-		g_waitfor_event(md_zapit, sc->gp, M_WAITOK, sc->gp, NULL);
+		g_wither_geom(sc->gp, ENXIO);
 		sc->gp =3D NULL;
 		sc->pp =3D NULL;
 	}
@@ -955,24 +955,27 @@
 	wakeup(sc);
 	while (sc->procp !=3D NULL)
 		tsleep(&sc->procp, PRIBIO, "mddestroy", hz / 10);
-	if (sc->vnode !=3D NULL)
-		(void)vn_close(sc->vnode, sc->flags & MD_READONLY ?
-		    FREAD : (FREAD|FWRITE), sc->cred, td);
+	if (sc->vnode !=3D NULL) {
+		int flags;
+
+		flags =3D FREAD;
+		if ((sc->flags & MD_READONLY) =3D=3D 0)
+			flags |=3D FWRITE;
+		vn_close(sc->vnode, flags, sc->cred, curthread);
+	}
 	if (sc->cred !=3D NULL)
 		crfree(sc->cred);
-	if (sc->object !=3D NULL) {
+	if (sc->object !=3D NULL)
 		vm_object_deallocate(sc->object);
-	}
-	if (sc->indir)
+	if (sc->indir !=3D NULL)
 		destroy_indir(sc, sc->indir);
-	if (sc->uma)
+	if (sc->uma !=3D NULL)
 		uma_zdestroy(sc->uma);
=20
 	/* XXX: LOCK(unique unit numbers) */
 	LIST_REMOVE(sc, list);
 	/* XXX: UNLOCK(unique unit numbers) */
 	free(sc, M_MD);
-	return (0);
 }
=20
 static int
@@ -1000,7 +1003,7 @@
 	 */
=20
 	if (mdio->md_size =3D=3D 0) {
-		mddestroy(sc, td);
+		mddestroy(sc);
 		return (EDOM);
 	}
=20
@@ -1015,45 +1018,58 @@
=20
 	sc->secsize =3D PAGE_SIZE;
 	sc->nsect =3D mdio->md_size / (PAGE_SIZE / DEV_BSIZE);
-	sc->object =3D vm_pager_allocate(OBJT_SWAP, NULL, sc->secsize * (vm_offse=
t_t)sc->nsect, VM_PROT_DEFAULT, 0);
+	sc->object =3D vm_pager_allocate(OBJT_SWAP, NULL,
+	    sc->secsize * (vm_offset_t)sc->nsect, VM_PROT_DEFAULT, 0);
 	sc->flags =3D mdio->md_options & MD_FORCE;
-	if (mdio->md_options & MD_RESERVE) {
+	if ((mdio->md_options & MD_RESERVE) !=3D 0) {
 		if (swap_pager_reserve(sc->object, 0, sc->nsect) < 0) {
 			vm_object_deallocate(sc->object);
 			sc->object =3D NULL;
-			mddestroy(sc, td);
+			mddestroy(sc);
 			return (EDOM);
 		}
 	}
 	error =3D mdsetcred(sc, td->td_ucred);
-	if (error) {
-		mddestroy(sc, td);
+	if (error !=3D 0) {
+		mddestroy(sc);
 		return (error);
 	}
 	mdinit(sc);
-	if (!(mdio->md_options & MD_RESERVE))
+	if ((mdio->md_options & MD_RESERVE) =3D=3D 0)
 		sc->pp->flags |=3D G_PF_CANDELETE;
 	return (0);
 }
=20
-static int
-mddetach(int unit, struct thread *td)
+static void
+mddetach(void *p, int cancel)
 {
 	struct md_s *sc;
+	struct md_tmp *tmp;
=20
-	sc =3D mdfind(unit);
-	if (sc =3D=3D NULL)
-		return (ENOENT);
-	if (sc->opencount !=3D 0 && !(sc->flags & MD_FORCE))
-		return (EBUSY);
+	if (cancel !=3D 0)
+		return;
+	tmp =3D p;
+
+	sc =3D mdfind(tmp->unit);
+	if (sc =3D=3D NULL) {
+		tmp->error =3D ENOENT;
+		return;
+	}
+	if (sc->opencount !=3D 0 && (sc->flags & MD_FORCE) =3D=3D 0) {
+		tmp->error =3D EBUSY;
+		return;
+	}
 	switch(sc->type) {
 	case MD_VNODE:
 	case MD_SWAP:
 	case MD_MALLOC:
 	case MD_PRELOAD:
-		return (mddestroy(sc, td));
+		tmp->error =3D 0;
+		mddestroy(sc);
+		return;
 	default:
-		return (EOPNOTSUPP);
+		tmp->error =3D EOPNOTSUPP;
+		return;
 	}
 }
=20
@@ -1064,9 +1080,10 @@
 	struct md_s *sc;
 	int i;
=20
-	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);
+	}
=20
 	/*
 	 * 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 !=3D MDIOVERSION)
 			return (EINVAL);
 		if (mdio->md_file !=3D NULL || mdio->md_size !=3D 0 ||
-		    mdio->md_options !=3D 0)
+		    mdio->md_options !=3D 0) {
 			return (EINVAL);
-		return (mddetach(mdio->md_unit, td));
+		}
+
+		tmp =3D malloc(sizeof(*tmp), M_TEMP, M_WAITOK | M_ZERO);
+		tmp->unit =3D mdio->md_unit;
+		g_waitfor_event(mddetach, tmp, M_WAITOK, tmp, NULL);
+		error =3D tmp->error;
+		free(tmp, M_TEMP);
+
+		return (error);
+	}
 	case MDIOCQUERY:
 		if (mdio->md_version !=3D 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 =3D=3D NULL)
 			continue;
-		if (strcmp(type, "md_image") && strcmp(type, "mfs_root"))
+		if (strcmp(type, "md_image") !=3D 0 &&
+		    strcmp(type, "mfs_root") !=3D 0) {
 			continue;
+		}
 		c =3D preload_search_info(mod, MODINFO_ADDR);
 		ptr =3D *(u_char **)c;
 		c =3D preload_search_info(mod, MODINFO_SIZE);
@@ -1195,39 +1225,37 @@
 	g_topology_lock();
 }
=20
+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 =3D 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 *g=
p)
 {
-	int error;
 	struct md_s *sc;
+	struct md_tmp tmp;
=20
-	switch (type) {
-	case MOD_LOAD:
-		break;
-	case MOD_UNLOAD:
-		LIST_FOREACH(sc, &md_softc_list, list) {
-			error =3D mddetach(sc->unit, curthread);
-			if (error !=3D 0)
-				return (error);
-		}
-		if (status_dev)
-			destroy_dev(status_dev);
-		status_dev =3D 0;
-		break;
-	default:
-		break;
-	}
-	return (0);
+	g_topology_assert();
+	sc =3D gp->softc;
+
+	tmp.unit =3D sc->unit;
+	tmp.error =3D 0;
+	mtx_lock(&Giant);
+	mddetach(&tmp, 0);
+	mtx_unlock(&Giant);
+
+	return (tmp.error);
 }
=20
-static moduledata_t md_mod =3D {
-	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);
-
=20
 #ifdef MD_ROOT
 static void

--w7PDEPdKQumQfZlR--

--veXX9dWIonWZEC6h
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (FreeBSD)

iQCVAwUBQAFysj/PhmMH/Mf1AQGh/gQAgWKQEfDuK4RVR9SQ8MIO9LMFYrkh98AO
0FXT31bkjmbVxQdo/aPBP+pnCeWZCgx9G+n1hKObFm1vFzWIrY9HiblcMkZd7BKs
sGn9y82uEEmZF6BS+npLCxzLOfkvsA3MluNnuyRmQEKYgxv2OovHBp92u+x3KDQL
W/dQ1ld/yw0=
=Kha9
-----END PGP SIGNATURE-----

--veXX9dWIonWZEC6h--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040111155842.GB74246>