Index: kern/kern_jail.c =================================================================== RCS file: /data/ncvs/src/sys/kern/kern_jail.c,v retrieving revision 1.34 diff -u -r1.34 kern_jail.c --- kern/kern_jail.c 11 Jun 2003 00:56:55 -0000 1.34 +++ kern/kern_jail.c 20 Jan 2004 20:28:20 -0000 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -60,6 +61,7 @@ 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 @@ prison_free(struct prison *pr) { - mtx_assert(&Giant, MA_OWNED); mtx_lock(&allprison_mtx); mtx_lock(&pr->pr_mtx); pr->pr_ref--; @@ -264,15 +265,30 @@ 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 Index: sys/_task.h =================================================================== RCS file: sys/_task.h diff -N sys/_task.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/_task.h 23 Jan 2004 19:07:24 -0000 @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 2000 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/sys/taskqueue.h,v 1.9 2003/09/05 23:09:22 sam Exp $ + */ + +#ifndef _SYS__TASK_H_ +#define _SYS__TASK_H_ + +#ifndef _KERNEL +#error "no user-servicable parts inside" +#endif + +#include + +/* + * Each task includes a function which is called from + * taskqueue_run(). The first argument is taken from the 'ta_context' + * field of struct task and the second argument is a count of how many + * times the task was enqueued before the call to taskqueue_run(). + */ +typedef void task_fn_t(void *context, int pending); + +struct task { + STAILQ_ENTRY(task) ta_link; /* link for queue */ + int ta_pending; /* count times queued */ + int ta_priority; /* priority of task in queue */ + task_fn_t *ta_func; /* task handler */ + void *ta_context; /* argument for handler */ +}; + +#endif /* !_SYS__TASK_H_ */ Index: sys/jail.h =================================================================== RCS file: /data/ncvs/src/sys/sys/jail.h,v retrieving revision 1.18 diff -u -r1.18 jail.h --- sys/jail.h 9 Apr 2003 02:55:18 -0000 1.18 +++ sys/jail.h 23 Jan 2004 19:08:16 -0000 @@ -39,6 +39,7 @@ #include #include #include +#include #define JAIL_MAX 999999 @@ -56,8 +57,8 @@ * (p) locked by pr_mutex * (c) set only during creation before the structure is shared, no mutex * required to read + * (d) set only during destruction of jail, no mutex needed */ -struct mtx; struct prison { LIST_ENTRY(prison) pr_list; /* (a) all prisons */ int pr_id; /* (c) prison id */ @@ -68,6 +69,7 @@ u_int32_t pr_ip; /* (c) ip addr host */ void *pr_linux; /* (p) linux abi */ int pr_securelevel; /* (p) securelevel */ + struct task pr_task; /* (d) destroy task */ struct mtx pr_mtx; }; Index: sys/taskqueue.h =================================================================== RCS file: /data/ncvs/src/sys/sys/taskqueue.h,v retrieving revision 1.9 diff -u -r1.9 taskqueue.h --- sys/taskqueue.h 5 Sep 2003 23:09:22 -0000 1.9 +++ sys/taskqueue.h 23 Jan 2004 19:07:52 -0000 @@ -34,18 +34,11 @@ #endif #include +#include struct taskqueue; /* - * Each task includes a function which is called from - * taskqueue_run(). The first argument is taken from the 'ta_context' - * field of struct task and the second argument is a count of how many - * times the task was enqueued before the call to taskqueue_run(). - */ -typedef void task_fn_t(void *context, int pending); - -/* * A notification callback function which is called from * taskqueue_enqueue(). The context argument is given in the call to * taskqueue_create(). This function would normally be used to allow the @@ -53,14 +46,6 @@ * interrupt or waking a kernel thread). */ typedef void (*taskqueue_enqueue_fn)(void *context); - -struct task { - STAILQ_ENTRY(task) ta_link; /* link for queue */ - int ta_pending; /* count times queued */ - int ta_priority; /* priority of task in queue */ - task_fn_t *ta_func; /* task handler */ - void *ta_context; /* argument for handler */ -}; struct taskqueue *taskqueue_create(const char *name, int mflags, taskqueue_enqueue_fn enqueue,