arena: check for imports when destroying

This catches bugs where we tear down an arena while other arenas or
slabs still depend on it.  It's the equivalent of a use-after-free.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
diff --git a/kern/src/arena.c b/kern/src/arena.c
index 6f6e400..c23ac41 100644
--- a/kern/src/arena.c
+++ b/kern/src/arena.c
@@ -274,11 +274,32 @@
 	return arena;
 }
 
+static bool __has_importer(struct arena *arena)
+{
+	struct arena *a_i;
+	struct kmem_cache *kc_i;
+
+	TAILQ_FOREACH(a_i, &arena->__importing_arenas, import_link) {
+		if (a_i != arena)
+			return true;
+	}
+	TAILQ_FOREACH(kc_i, &arena->__importing_slabs, import_link) {
+		if (!(kc_i->flags & KMC_QCACHE))
+			return true;
+	}
+	return false;
+}
+
 void arena_destroy(struct arena *arena)
 {
 	struct btag *bt_i, *temp;
 
 	qlock(&arenas_and_slabs_lock);
+	if (__has_importer(arena)) {
+		warn("Arena %s has importers!  Will not destroy.", arena->name);
+		qunlock(&arenas_and_slabs_lock);
+		return;
+	}
 	TAILQ_REMOVE(&all_arenas, arena, next);
 	qunlock(&arenas_and_slabs_lock);
 	if (arena->source)