move daemonized kernel threads into the swapper's session
[powerpc.git] / kernel / pid.c
index f76097c..939746f 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/hash.h>
 #include <linux/pid_namespace.h>
 #include <linux/init_task.h>
+#include <linux/syscalls.h>
 
 #define pid_hashfn(nr, ns)     \
        hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
@@ -179,7 +180,7 @@ static int alloc_pidmap(struct pid_namespace *pid_ns)
        return -1;
 }
 
-static int next_pidmap(struct pid_namespace *pid_ns, int last)
+int next_pidmap(struct pid_namespace *pid_ns, int last)
 {
        int offset;
        struct pidmap *map, *end;
@@ -261,7 +262,6 @@ struct pid *alloc_pid(struct pid_namespace *ns)
 
        get_pid_ns(ns);
        pid->level = ns->level;
-       pid->nr = pid->numbers[0].nr;
        atomic_set(&pid->count, 1);
        for (type = 0; type < PIDTYPE_MAX; ++type)
                INIT_HLIST_HEAD(&pid->tasks[type]);
@@ -301,6 +301,18 @@ struct pid * fastcall find_pid_ns(int nr, struct pid_namespace *ns)
 }
 EXPORT_SYMBOL_GPL(find_pid_ns);
 
+struct pid *find_vpid(int nr)
+{
+       return find_pid_ns(nr, current->nsproxy->pid_ns);
+}
+EXPORT_SYMBOL_GPL(find_vpid);
+
+struct pid *find_pid(int nr)
+{
+       return find_pid_ns(nr, &init_pid_ns);
+}
+EXPORT_SYMBOL_GPL(find_pid);
+
 /*
  * attach_pid() must be called with the tasklist_lock write-held.
  */
@@ -355,6 +367,7 @@ struct task_struct * fastcall pid_task(struct pid *pid, enum pid_type type)
        }
        return result;
 }
+EXPORT_SYMBOL(pid_task);
 
 /*
  * Must be called under rcu_read_lock() or with tasklist_lock read-held.
@@ -367,6 +380,25 @@ struct task_struct *find_task_by_pid_type_ns(int type, int nr,
 
 EXPORT_SYMBOL(find_task_by_pid_type_ns);
 
+struct task_struct *find_task_by_pid(pid_t nr)
+{
+       return find_task_by_pid_type_ns(PIDTYPE_PID, nr, &init_pid_ns);
+}
+EXPORT_SYMBOL(find_task_by_pid);
+
+struct task_struct *find_task_by_vpid(pid_t vnr)
+{
+       return find_task_by_pid_type_ns(PIDTYPE_PID, vnr,
+                       current->nsproxy->pid_ns);
+}
+EXPORT_SYMBOL(find_task_by_vpid);
+
+struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns)
+{
+       return find_task_by_pid_type_ns(PIDTYPE_PID, nr, ns);
+}
+EXPORT_SYMBOL(find_task_by_pid_ns);
+
 struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
 {
        struct pid *pid;
@@ -411,6 +443,30 @@ pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
        return nr;
 }
 
+pid_t task_pid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+       return pid_nr_ns(task_pid(tsk), ns);
+}
+EXPORT_SYMBOL(task_pid_nr_ns);
+
+pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+       return pid_nr_ns(task_tgid(tsk), ns);
+}
+EXPORT_SYMBOL(task_tgid_nr_ns);
+
+pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+       return pid_nr_ns(task_pgrp(tsk), ns);
+}
+EXPORT_SYMBOL(task_pgrp_nr_ns);
+
+pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+       return pid_nr_ns(task_session(tsk), ns);
+}
+EXPORT_SYMBOL(task_session_nr_ns);
+
 /*
  * Used by proc to find the first pid that is greater then or equal to nr.
  *
@@ -431,141 +487,6 @@ struct pid *find_ge_pid(int nr, struct pid_namespace *ns)
 }
 EXPORT_SYMBOL_GPL(find_get_pid);
 
-struct pid_cache {
-       int nr_ids;
-       char name[16];
-       struct kmem_cache *cachep;
-       struct list_head list;
-};
-
-static LIST_HEAD(pid_caches_lh);
-static DEFINE_MUTEX(pid_caches_mutex);
-
-/*
- * creates the kmem cache to allocate pids from.
- * @nr_ids: the number of numerical ids this pid will have to carry
- */
-
-static struct kmem_cache *create_pid_cachep(int nr_ids)
-{
-       struct pid_cache *pcache;
-       struct kmem_cache *cachep;
-
-       mutex_lock(&pid_caches_mutex);
-       list_for_each_entry (pcache, &pid_caches_lh, list)
-               if (pcache->nr_ids == nr_ids)
-                       goto out;
-
-       pcache = kmalloc(sizeof(struct pid_cache), GFP_KERNEL);
-       if (pcache == NULL)
-               goto err_alloc;
-
-       snprintf(pcache->name, sizeof(pcache->name), "pid_%d", nr_ids);
-       cachep = kmem_cache_create(pcache->name,
-                       sizeof(struct pid) + (nr_ids - 1) * sizeof(struct upid),
-                       0, SLAB_HWCACHE_ALIGN, NULL);
-       if (cachep == NULL)
-               goto err_cachep;
-
-       pcache->nr_ids = nr_ids;
-       pcache->cachep = cachep;
-       list_add(&pcache->list, &pid_caches_lh);
-out:
-       mutex_unlock(&pid_caches_mutex);
-       return pcache->cachep;
-
-err_cachep:
-       kfree(pcache);
-err_alloc:
-       mutex_unlock(&pid_caches_mutex);
-       return NULL;
-}
-
-static struct pid_namespace *create_pid_namespace(int level)
-{
-       struct pid_namespace *ns;
-       int i;
-
-       ns = kmalloc(sizeof(struct pid_namespace), GFP_KERNEL);
-       if (ns == NULL)
-               goto out;
-
-       ns->pidmap[0].page = kzalloc(PAGE_SIZE, GFP_KERNEL);
-       if (!ns->pidmap[0].page)
-               goto out_free;
-
-       ns->pid_cachep = create_pid_cachep(level + 1);
-       if (ns->pid_cachep == NULL)
-               goto out_free_map;
-
-       kref_init(&ns->kref);
-       ns->last_pid = 0;
-       ns->child_reaper = NULL;
-       ns->level = level;
-
-       set_bit(0, ns->pidmap[0].page);
-       atomic_set(&ns->pidmap[0].nr_free, BITS_PER_PAGE - 1);
-
-       for (i = 1; i < PIDMAP_ENTRIES; i++) {
-               ns->pidmap[i].page = 0;
-               atomic_set(&ns->pidmap[i].nr_free, BITS_PER_PAGE);
-       }
-
-       return ns;
-
-out_free_map:
-       kfree(ns->pidmap[0].page);
-out_free:
-       kfree(ns);
-out:
-       return ERR_PTR(-ENOMEM);
-}
-
-static void destroy_pid_namespace(struct pid_namespace *ns)
-{
-       int i;
-
-       for (i = 0; i < PIDMAP_ENTRIES; i++)
-               kfree(ns->pidmap[i].page);
-       kfree(ns);
-}
-
-struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *old_ns)
-{
-       struct pid_namespace *new_ns;
-
-       BUG_ON(!old_ns);
-       new_ns = get_pid_ns(old_ns);
-       if (!(flags & CLONE_NEWPID))
-               goto out;
-
-       new_ns = ERR_PTR(-EINVAL);
-       if (flags & CLONE_THREAD)
-               goto out_put;
-
-       new_ns = create_pid_namespace(old_ns->level + 1);
-       if (!IS_ERR(new_ns))
-               new_ns->parent = get_pid_ns(old_ns);
-
-out_put:
-       put_pid_ns(old_ns);
-out:
-       return new_ns;
-}
-
-void free_pid_ns(struct kref *kref)
-{
-       struct pid_namespace *ns, *parent;
-
-       ns = container_of(kref, struct pid_namespace, kref);
-
-       parent = ns->parent;
-       destroy_pid_namespace(ns);
-
-       if (parent != NULL)
-               put_pid_ns(parent);
-}
-
 /*
  * The pid hash table is scaled according to the amount of memory in the
  * machine.  From a minimum of 16 slots up to 4096 slots at one gigabyte or
@@ -598,7 +519,6 @@ void __init pidmap_init(void)
        set_bit(0, init_pid_ns.pidmap[0].page);
        atomic_dec(&init_pid_ns.pidmap[0].nr_free);
 
-       init_pid_ns.pid_cachep = create_pid_cachep(1);
-       if (init_pid_ns.pid_cachep == NULL)
-               panic("Can't create pid_1 cachep\n");
+       init_pid_ns.pid_cachep = KMEM_CACHE(pid,
+                       SLAB_HWCACHE_ALIGN | SLAB_PANIC);
 }