diff options
author | Robert Watson <rwatson@FreeBSD.org> | 2004-01-23 20:44:26 +0000 |
---|---|---|
committer | Robert Watson <rwatson@FreeBSD.org> | 2004-01-23 20:44:26 +0000 |
commit | b3059e09f641e252e516532795728d385ed068d7 (patch) | |
tree | cad255f8a586699981e032637c52523632e2f1bc /sys/kern/kern_jail.c | |
parent | f5b3481451587f4c4cf164f9dae5cf7cf798e8c3 (diff) | |
download | src-b3059e09f641e252e516532795728d385ed068d7.tar.gz src-b3059e09f641e252e516532795728d385ed068d7.zip |
Notes
Diffstat (limited to 'sys/kern/kern_jail.c')
-rw-r--r-- | sys/kern/kern_jail.c | 28 |
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) { |