aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/md/md.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/md/md.c')
-rw-r--r--sys/dev/md/md.c54
1 files changed, 42 insertions, 12 deletions
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
index b842d4f2fd8e..ec1664fac701 100644
--- a/sys/dev/md/md.c
+++ b/sys/dev/md/md.c
@@ -11,9 +11,9 @@
*/
/*-
- * The following functions are based on the vn(4) driver: mdstart_swap(),
- * mdstart_vnode(), mdcreate_swap(), mdcreate_vnode() and mddestroy(),
- * and as such under the following copyright:
+ * The following functions are based on the historical vn(4) driver:
+ * mdstart_swap(), mdstart_vnode(), mdcreate_swap(), mdcreate_vnode()
+ * and mddestroy(), and as such under the following copyright:
*
* Copyright (c) 1988 University of Utah.
* Copyright (c) 1990, 1993
@@ -89,6 +89,8 @@
#include <sys/unistd.h>
#include <sys/vnode.h>
#include <sys/disk.h>
+#include <sys/param.h>
+#include <sys/bus.h>
#include <geom/geom.h>
#include <geom/geom_int.h>
@@ -1559,19 +1561,26 @@ mddestroy(struct md_s *sc, struct thread *td)
mtx_destroy(&sc->queue_mtx);
switch (sc->type) {
case MD_VNODE:
- vn_lock(sc->s_vnode.vnode, LK_EXCLUSIVE | LK_RETRY);
- sc->s_vnode.vnode->v_vflag &= ~VV_MD;
- VOP_UNLOCK(sc->s_vnode.vnode);
- (void)vn_close(sc->s_vnode.vnode, sc->flags & MD_READONLY ?
- FREAD : (FREAD|FWRITE), sc->cred, td);
- kva_free(sc->s_vnode.kva, maxphys + PAGE_SIZE);
+ if (sc->s_vnode.vnode != NULL) {
+ vn_lock(sc->s_vnode.vnode, LK_EXCLUSIVE | LK_RETRY);
+ sc->s_vnode.vnode->v_vflag &= ~VV_MD;
+ VOP_UNLOCK(sc->s_vnode.vnode);
+ (void)vn_close(sc->s_vnode.vnode,
+ sc->flags & MD_READONLY ? FREAD : (FREAD|FWRITE),
+ sc->cred, td);
+ }
+ if (sc->s_vnode.kva != 0)
+ kva_free(sc->s_vnode.kva, maxphys + PAGE_SIZE);
break;
case MD_SWAP:
- vm_object_deallocate(sc->s_swap.object);
+ if (sc->s_swap.object != NULL)
+ vm_object_deallocate(sc->s_swap.object);
break;
case MD_MALLOC:
- destroy_indir(sc, sc->s_malloc.indir);
- uma_zdestroy(sc->s_malloc.uma);
+ if (sc->s_malloc.indir != NULL)
+ destroy_indir(sc, sc->s_malloc.indir);
+ if (sc->s_malloc.uma != NULL)
+ uma_zdestroy(sc->s_malloc.uma);
break;
case MD_PRELOAD:
case MD_NULL:
@@ -2075,8 +2084,10 @@ g_md_init(struct g_class *mp __unused)
{
caddr_t mod;
u_char *ptr, *name, *type;
+ u_char scratch[40];
unsigned len;
int i;
+ vm_offset_t paddr;
/* figure out log2(NINDIR) */
for (i = NINDIR, nshift = -1; i; nshift++)
@@ -2116,6 +2127,25 @@ g_md_init(struct g_class *mp __unused)
sx_xunlock(&md_sx);
}
}
+
+ /*
+ * Load up to 32 pre-loaded disks
+ */
+ for (int i = 0; i < 32; i++) {
+ if (resource_long_value("md", i, "physaddr",
+ (long *) &paddr) != 0 ||
+ resource_int_value("md", i, "len", &len) != 0)
+ break;
+ ptr = (char *)pmap_map(NULL, paddr, paddr + len, VM_PROT_READ);
+ if (ptr != NULL && len != 0) {
+ sprintf(scratch, "preload%d 0x%016jx", i,
+ (uintmax_t)paddr);
+ sx_xlock(&md_sx);
+ md_preloaded(ptr, len, scratch);
+ sx_xunlock(&md_sx);
+ }
+ }
+
status_dev = make_dev(&mdctl_cdevsw, INT_MAX, UID_ROOT, GID_WHEEL,
0600, MDCTL_NAME);
g_topology_lock();