Skip to content

Commit

Permalink
[PATCH] proc: Fix the link count for /proc/<pid>/task
Browse files Browse the repository at this point in the history
Use getattr to get an accurate link count when needed.  This is cheaper and
more accurate than trying to derive it by walking the thread list of a
process.

Especially as it happens when needed stat instead of at readdir time.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Eric W. Biederman authored and Linus Torvalds committed Jun 26, 2006
1 parent 0f2fe20 commit 6e66b52
Showing 1 changed file with 19 additions and 2 deletions.
21 changes: 19 additions & 2 deletions fs/proc/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -1532,6 +1532,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,

static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir);
static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd);
static int proc_task_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);

static struct file_operations proc_fd_operations = {
.read = generic_read_dir,
Expand All @@ -1552,6 +1553,7 @@ static struct inode_operations proc_fd_inode_operations = {

static struct inode_operations proc_task_inode_operations = {
.lookup = proc_task_lookup,
.getattr = proc_task_getattr,
};

#ifdef CONFIG_SECURITY
Expand Down Expand Up @@ -1658,7 +1660,7 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
*/
switch(p->type) {
case PROC_TGID_TASK:
inode->i_nlink = 2 + get_tid_list(2, NULL, dir);
inode->i_nlink = 2;
inode->i_op = &proc_task_inode_operations;
inode->i_fop = &proc_task_operations;
break;
Expand Down Expand Up @@ -2261,7 +2263,6 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi
}

nr_tids = get_tid_list(pos, tid_array, inode);
inode->i_nlink = pos + nr_tids;

for (i = 0; i < nr_tids; i++) {
unsigned long j = PROC_NUMBUF;
Expand All @@ -2281,3 +2282,19 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi
filp->f_pos = pos;
return retval;
}

static int proc_task_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
{
struct inode *inode = dentry->d_inode;
struct task_struct *p = proc_task(inode);
generic_fillattr(inode, stat);

if (pid_alive(p)) {
task_lock(p);
if (p->signal)
stat->nlink += atomic_read(&p->signal->count);
task_unlock(p);
}

return 0;
}

0 comments on commit 6e66b52

Please sign in to comment.