aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_jail.c
diff options
context:
space:
mode:
authorRobert Watson <rwatson@FreeBSD.org>2004-01-23 20:44:26 +0000
committerRobert Watson <rwatson@FreeBSD.org>2004-01-23 20:44:26 +0000
commitb3059e09f641e252e516532795728d385ed068d7 (patch)
treecad255f8a586699981e032637c52523632e2f1bc /sys/kern/kern_jail.c
parentf5b3481451587f4c4cf164f9dae5cf7cf798e8c3 (diff)
downloadsrc-b3059e09f641e252e516532795728d385ed068d7.tar.gz
src-b3059e09f641e252e516532795728d385ed068d7.zip
Notes
Diffstat (limited to 'sys/kern/kern_jail.c')
-rw-r--r--sys/kern/kern_jail.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 2241dd6caec2..79be2492ccc9 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -18,6 +18,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysproto.h>
#include <sys/malloc.h>
#include <sys/proc.h>
+#include <sys/taskqueue.h>
#include <sys/jail.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -60,6 +61,7 @@ int lastprid = 0;
int prisoncount = 0;
static void init_prison(void *);
+static void prison_complete(void *context, int pending);
static struct prison *prison_find(int);
static int sysctl_jail_list(SYSCTL_HANDLER_ARGS);
@@ -255,7 +257,6 @@ void
prison_free(struct prison *pr)
{
- mtx_assert(&Giant, MA_OWNED);
mtx_lock(&allprison_mtx);
mtx_lock(&pr->pr_mtx);
pr->pr_ref--;
@@ -264,17 +265,32 @@ prison_free(struct prison *pr)
mtx_unlock(&pr->pr_mtx);
prisoncount--;
mtx_unlock(&allprison_mtx);
- vrele(pr->pr_root);
- mtx_destroy(&pr->pr_mtx);
- if (pr->pr_linux != NULL)
- FREE(pr->pr_linux, M_PRISON);
- FREE(pr, M_PRISON);
+
+ TASK_INIT(&pr->pr_task, 0, prison_complete, pr);
+ taskqueue_enqueue(taskqueue_swi, &pr->pr_task);
return;
}
mtx_unlock(&pr->pr_mtx);
mtx_unlock(&allprison_mtx);
}
+static void
+prison_complete(void *context, int pending)
+{
+ struct prison *pr;
+
+ pr = (struct prison *)context;
+
+ mtx_lock(&Giant);
+ vrele(pr->pr_root);
+ mtx_unlock(&Giant);
+
+ mtx_destroy(&pr->pr_mtx);
+ if (pr->pr_linux != NULL)
+ FREE(pr->pr_linux, M_PRISON);
+ FREE(pr, M_PRISON);
+}
+
void
prison_hold(struct prison *pr)
{