Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 74351
b: refs/heads/master
c: 19fd4bb
h: refs/heads/master
i:
  74349: 3b76f76
  74347: 6ac47b1
  74343: faf90db
  74335: 1c695d8
v: v3
  • Loading branch information
Eric W. Biederman authored and Linus Torvalds committed Nov 29, 2007
1 parent 76de2ae commit 438dcd5
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 24 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: c895078355b6b6e05c60aa205892526dd3390f0a
refs/heads/master: 19fd4bb2a0cfede054e4904e0b167e0ca4f36cc7
51 changes: 28 additions & 23 deletions trunk/fs/proc/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -2411,19 +2411,23 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
* Find the first task with tgid >= tgid
*
*/
static struct task_struct *next_tgid(unsigned int tgid,
struct pid_namespace *ns)
{
struct tgid_iter {
unsigned int tgid;
struct task_struct *task;
};
static struct tgid_iter next_tgid(struct pid_namespace *ns, struct tgid_iter iter)
{
struct pid *pid;

if (iter.task)
put_task_struct(iter.task);
rcu_read_lock();
retry:
task = NULL;
pid = find_ge_pid(tgid, ns);
iter.task = NULL;
pid = find_ge_pid(iter.tgid, ns);
if (pid) {
tgid = pid_nr_ns(pid, ns) + 1;
task = pid_task(pid, PIDTYPE_PID);
iter.tgid = pid_nr_ns(pid, ns);
iter.task = pid_task(pid, PIDTYPE_PID);
/* What we to know is if the pid we have find is the
* pid of a thread_group_leader. Testing for task
* being a thread_group_leader is the obvious thing
Expand All @@ -2436,32 +2440,33 @@ static struct task_struct *next_tgid(unsigned int tgid,
* found doesn't happen to be a thread group leader.
* As we don't care in the case of readdir.
*/
if (!task || !has_group_leader_pid(task))
if (!iter.task || !has_group_leader_pid(iter.task)) {
iter.tgid += 1;
goto retry;
get_task_struct(task);
}
get_task_struct(iter.task);
}
rcu_read_unlock();
return task;
return iter;
}

#define TGID_OFFSET (FIRST_PROCESS_ENTRY + ARRAY_SIZE(proc_base_stuff))

static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
struct task_struct *task, int tgid)
struct tgid_iter iter)
{
char name[PROC_NUMBUF];
int len = snprintf(name, sizeof(name), "%d", tgid);
int len = snprintf(name, sizeof(name), "%d", iter.tgid);
return proc_fill_cache(filp, dirent, filldir, name, len,
proc_pid_instantiate, task, NULL);
proc_pid_instantiate, iter.task, NULL);
}

/* for the /proc/ directory itself, after non-process stuff has been done */
int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
{
unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
struct task_struct *task;
int tgid;
struct tgid_iter iter;
struct pid_namespace *ns;

if (!reaper)
Expand All @@ -2474,14 +2479,14 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
}

ns = filp->f_dentry->d_sb->s_fs_info;
tgid = filp->f_pos - TGID_OFFSET;
for (task = next_tgid(tgid, ns);
task;
put_task_struct(task), task = next_tgid(tgid + 1, ns)) {
tgid = task_pid_nr_ns(task, ns);
filp->f_pos = tgid + TGID_OFFSET;
if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) {
put_task_struct(task);
iter.task = NULL;
iter.tgid = filp->f_pos - TGID_OFFSET;
for (iter = next_tgid(ns, iter);
iter.task;
iter.tgid += 1, iter = next_tgid(ns, iter)) {
filp->f_pos = iter.tgid + TGID_OFFSET;
if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
put_task_struct(iter.task);
goto out;
}
}
Expand Down

0 comments on commit 438dcd5

Please sign in to comment.