Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 71449
b: refs/heads/master
c: 198fe21
h: refs/heads/master
i:
  71447: ea78ba4
v: v3
  • Loading branch information
Pavel Emelyanov authored and Linus Torvalds committed Oct 19, 2007
1 parent 1a486c6 commit 29d0ed0
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 23 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7af5729474b5b8ad385adadab78d6e723e7655a3
refs/heads/master: 198fe21b0a17fe9c68cb519ecc566534b04f122b
2 changes: 1 addition & 1 deletion trunk/fs/proc/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -2333,7 +2333,7 @@ static struct task_struct *next_tgid(unsigned int tgid)
rcu_read_lock();
retry:
task = NULL;
pid = find_ge_pid(tgid);
pid = find_ge_pid(tgid, &init_pid_ns);
if (pid) {
tgid = pid->nr + 1;
task = pid_task(pid, PIDTYPE_PID);
Expand Down
16 changes: 14 additions & 2 deletions trunk/include/linux/pid.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,17 +99,29 @@ extern void FASTCALL(detach_pid(struct task_struct *task, enum pid_type));
extern void FASTCALL(transfer_pid(struct task_struct *old,
struct task_struct *new, enum pid_type));

struct pid_namespace;
extern struct pid_namespace init_pid_ns;

/*
* look up a PID in the hash table. Must be called with the tasklist_lock
* or rcu_read_lock() held.
*
* find_pid_ns() finds the pid in the namespace specified
* find_pid() find the pid by its global id, i.e. in the init namespace
* find_vpid() finr the pid by its virtual id, i.e. in the current namespace
*
* see also find_task_by_pid() set in include/linux/sched.h
*/
extern struct pid *FASTCALL(find_pid(int nr));
extern struct pid *FASTCALL(find_pid_ns(int nr, struct pid_namespace *ns));

#define find_vpid(pid) find_pid_ns(pid, current->nsproxy->pid_ns)
#define find_pid(pid) find_pid_ns(pid, &init_pid_ns)

/*
* Lookup a PID in the hash table, and return with it's count elevated.
*/
extern struct pid *find_get_pid(int nr);
extern struct pid *find_ge_pid(int nr);
extern struct pid *find_ge_pid(int nr, struct pid_namespace *);

extern struct pid *alloc_pid(struct pid_namespace *ns);
extern void FASTCALL(free_pid(struct pid *pid));
Expand Down
31 changes: 29 additions & 2 deletions trunk/include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -1514,8 +1514,35 @@ extern struct task_struct init_task;

extern struct mm_struct init_mm;

#define find_task_by_pid(nr) find_task_by_pid_type(PIDTYPE_PID, nr)
extern struct task_struct *find_task_by_pid_type(int type, int pid);
extern struct pid_namespace init_pid_ns;

/*
* find a task by one of its numerical ids
*
* find_task_by_pid_type_ns():
* it is the most generic call - it finds a task by all id,
* type and namespace specified
* find_task_by_pid_ns():
* finds a task by its pid in the specified namespace
* find_task_by_pid_type():
* finds a task by its global id with the specified type, e.g.
* by global session id
* find_task_by_pid():
* finds a task by its global pid
*
* see also find_pid() etc in include/linux/pid.h
*/

extern struct task_struct *find_task_by_pid_type_ns(int type, int pid,
struct pid_namespace *ns);

#define find_task_by_pid_ns(nr, ns) \
find_task_by_pid_type_ns(PIDTYPE_PID, nr, ns)
#define find_task_by_pid_type(type, nr) \
find_task_by_pid_type_ns(type, nr, &init_pid_ns)
#define find_task_by_pid(nr) \
find_task_by_pid_type(PIDTYPE_PID, nr)

extern void __set_special_pids(pid_t session, pid_t pgrp);

/* per-UID process charging. */
Expand Down
43 changes: 26 additions & 17 deletions trunk/kernel/pid.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ struct pid_namespace init_pid_ns = {
.level = 0,
.child_reaper = &init_task,
};
EXPORT_SYMBOL_GPL(init_pid_ns);

int is_global_init(struct task_struct *tsk)
{
Expand Down Expand Up @@ -210,7 +211,8 @@ fastcall void free_pid(struct pid *pid)
unsigned long flags;

spin_lock_irqsave(&pidmap_lock, flags);
hlist_del_rcu(&pid->pid_chain);
for (i = 0; i <= pid->level; i++)
hlist_del_rcu(&pid->numbers[i].pid_chain);
spin_unlock_irqrestore(&pidmap_lock, flags);

for (i = 0; i <= pid->level; i++)
Expand All @@ -225,6 +227,7 @@ struct pid *alloc_pid(struct pid_namespace *ns)
enum pid_type type;
int i, nr;
struct pid_namespace *tmp;
struct upid *upid;

pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL);
if (!pid)
Expand All @@ -251,7 +254,11 @@ struct pid *alloc_pid(struct pid_namespace *ns)
INIT_HLIST_HEAD(&pid->tasks[type]);

spin_lock_irq(&pidmap_lock);
hlist_add_head_rcu(&pid->pid_chain, &pid_hash[pid_hashfn(pid->nr, ns)]);
for (i = ns->level; i >= 0; i--) {
upid = &pid->numbers[i];
hlist_add_head_rcu(&upid->pid_chain,
&pid_hash[pid_hashfn(upid->nr, upid->ns)]);
}
spin_unlock_irq(&pidmap_lock);

out:
Expand All @@ -266,19 +273,20 @@ struct pid *alloc_pid(struct pid_namespace *ns)
goto out;
}

struct pid * fastcall find_pid(int nr)
struct pid * fastcall find_pid_ns(int nr, struct pid_namespace *ns)
{
struct hlist_node *elem;
struct pid *pid;
struct upid *pnr;

hlist_for_each_entry_rcu(pnr, elem,
&pid_hash[pid_hashfn(nr, ns)], pid_chain)
if (pnr->nr == nr && pnr->ns == ns)
return container_of(pnr, struct pid,
numbers[ns->level]);

hlist_for_each_entry_rcu(pid, elem,
&pid_hash[pid_hashfn(nr, &init_pid_ns)], pid_chain) {
if (pid->nr == nr)
return pid;
}
return NULL;
}
EXPORT_SYMBOL_GPL(find_pid);
EXPORT_SYMBOL_GPL(find_pid_ns);

/*
* attach_pid() must be called with the tasklist_lock write-held.
Expand Down Expand Up @@ -338,12 +346,13 @@ struct task_struct * fastcall pid_task(struct pid *pid, enum pid_type type)
/*
* Must be called under rcu_read_lock() or with tasklist_lock read-held.
*/
struct task_struct *find_task_by_pid_type(int type, int nr)
struct task_struct *find_task_by_pid_type_ns(int type, int nr,
struct pid_namespace *ns)
{
return pid_task(find_pid(nr), type);
return pid_task(find_pid_ns(nr, ns), type);
}

EXPORT_SYMBOL(find_task_by_pid_type);
EXPORT_SYMBOL(find_task_by_pid_type_ns);

struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
{
Expand All @@ -370,7 +379,7 @@ struct pid *find_get_pid(pid_t nr)
struct pid *pid;

rcu_read_lock();
pid = get_pid(find_pid(nr));
pid = get_pid(find_vpid(nr));
rcu_read_unlock();

return pid;
Expand All @@ -394,15 +403,15 @@ pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
*
* If there is a pid at nr this function is exactly the same as find_pid.
*/
struct pid *find_ge_pid(int nr)
struct pid *find_ge_pid(int nr, struct pid_namespace *ns)
{
struct pid *pid;

do {
pid = find_pid(nr);
pid = find_pid_ns(nr, ns);
if (pid)
break;
nr = next_pidmap(task_active_pid_ns(current), nr);
nr = next_pidmap(ns, nr);
} while (nr > 0);

return pid;
Expand Down

0 comments on commit 29d0ed0

Please sign in to comment.