diff options
author | Daniel Drake <dsd@gentoo.org> | 2005-05-01 11:59:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-05-01 11:59:03 -0400 |
commit | f246315e1ab96c40978777d1e159820ecca45aa8 (patch) | |
tree | 32ed8f99da48313838d5aa863f5d3e7ed984213f | |
parent | bcf88e1163623e8e8ef2ba7feface9c826a890c9 (diff) |
[PATCH] procfs: Fix hardlink counts for /proc/<PID>/task
The current logic assumes that a /proc/<PID>/task directory should have a
hardlink count of 3, probably counting ".", "..", and a directory for a
single child task.
It's fairly obvious that this doesn't work out correctly when a PID has
more than one child task, which is quite often the case.
Signed-off-by: Daniel Drake <dsd@gentoo.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | fs/proc/base.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index 4718173af2c8..2eac86d46c51 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1419,6 +1419,8 @@ static struct file_operations proc_tgid_attr_operations; | |||
1419 | static struct inode_operations proc_tgid_attr_inode_operations; | 1419 | static struct inode_operations proc_tgid_attr_inode_operations; |
1420 | #endif | 1420 | #endif |
1421 | 1421 | ||
1422 | static int get_tid_list(int index, unsigned int *tids, struct inode *dir); | ||
1423 | |||
1422 | /* SMP-safe */ | 1424 | /* SMP-safe */ |
1423 | static struct dentry *proc_pident_lookup(struct inode *dir, | 1425 | static struct dentry *proc_pident_lookup(struct inode *dir, |
1424 | struct dentry *dentry, | 1426 | struct dentry *dentry, |
@@ -1458,7 +1460,7 @@ static struct dentry *proc_pident_lookup(struct inode *dir, | |||
1458 | */ | 1460 | */ |
1459 | switch(p->type) { | 1461 | switch(p->type) { |
1460 | case PROC_TGID_TASK: | 1462 | case PROC_TGID_TASK: |
1461 | inode->i_nlink = 3; | 1463 | inode->i_nlink = 2 + get_tid_list(2, NULL, dir); |
1462 | inode->i_op = &proc_task_inode_operations; | 1464 | inode->i_op = &proc_task_inode_operations; |
1463 | inode->i_fop = &proc_task_operations; | 1465 | inode->i_fop = &proc_task_operations; |
1464 | break; | 1466 | break; |
@@ -1943,7 +1945,8 @@ static int get_tid_list(int index, unsigned int *tids, struct inode *dir) | |||
1943 | 1945 | ||
1944 | if (--index >= 0) | 1946 | if (--index >= 0) |
1945 | continue; | 1947 | continue; |
1946 | tids[nr_tids] = tid; | 1948 | if (tids != NULL) |
1949 | tids[nr_tids] = tid; | ||
1947 | nr_tids++; | 1950 | nr_tids++; |
1948 | if (nr_tids >= PROC_MAXPIDS) | 1951 | if (nr_tids >= PROC_MAXPIDS) |
1949 | break; | 1952 | break; |
@@ -2043,6 +2046,7 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi | |||
2043 | } | 2046 | } |
2044 | 2047 | ||
2045 | nr_tids = get_tid_list(pos, tid_array, inode); | 2048 | nr_tids = get_tid_list(pos, tid_array, inode); |
2049 | inode->i_nlink = pos + nr_tids; | ||
2046 | 2050 | ||
2047 | for (i = 0; i < nr_tids; i++) { | 2051 | for (i = 0; i < nr_tids; i++) { |
2048 | unsigned long j = PROC_NUMBUF; | 2052 | unsigned long j = PROC_NUMBUF; |