diff options
| author | 2009-03-04 02:29:19 +0100 | |
|---|---|---|
| committer | 2009-03-04 02:29:19 +0100 | |
| commit | 91d75e209bd59695f0708d66964d928d45b3b2f3 (patch) | |
| tree | 32cab1359d951e4193bebb181a0f0319824a2b95 /kernel/user_namespace.c | |
| parent | xen: deal with virtually mapped percpu data (diff) | |
| parent | Merge branches 'x86/apic', 'x86/cpu', 'x86/fixmap', 'x86/mm', 'x86/sched', 'x86/setup-lzma', 'x86/signal' and 'x86/urgent' into x86/core (diff) | |
| download | wireguard-linux-91d75e209bd59695f0708d66964d928d45b3b2f3.tar.xz wireguard-linux-91d75e209bd59695f0708d66964d928d45b3b2f3.zip | |
Merge branch 'x86/core' into core/percpu
Diffstat (limited to 'kernel/user_namespace.c')
| -rw-r--r-- | kernel/user_namespace.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 79084311ee57..076c7c8215b0 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -60,12 +60,25 @@ int create_user_ns(struct cred *new) return 0; } -void free_user_ns(struct kref *kref) +/* + * Deferred destructor for a user namespace. This is required because + * free_user_ns() may be called with uidhash_lock held, but we need to call + * back to free_uid() which will want to take the lock again. + */ +static void free_user_ns_work(struct work_struct *work) { - struct user_namespace *ns; - - ns = container_of(kref, struct user_namespace, kref); + struct user_namespace *ns = + container_of(work, struct user_namespace, destroyer); free_uid(ns->creator); kfree(ns); } + +void free_user_ns(struct kref *kref) +{ + struct user_namespace *ns = + container_of(kref, struct user_namespace, kref); + + INIT_WORK(&ns->destroyer, free_user_ns_work); + schedule_work(&ns->destroyer); +} EXPORT_SYMBOL(free_user_ns); |
