diff options
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/base.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index 6afca09a6534..36983e7bb2c1 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -74,6 +74,7 @@ | |||
74 | #include <linux/nsproxy.h> | 74 | #include <linux/nsproxy.h> |
75 | #include <linux/oom.h> | 75 | #include <linux/oom.h> |
76 | #include <linux/elf.h> | 76 | #include <linux/elf.h> |
77 | #include <linux/pid_namespace.h> | ||
77 | #include "internal.h" | 78 | #include "internal.h" |
78 | 79 | ||
79 | /* NOTE: | 80 | /* NOTE: |
@@ -2204,27 +2205,27 @@ static const struct inode_operations proc_tgid_base_inode_operations = { | |||
2204 | * that no dcache entries will exist at process exit time it | 2205 | * that no dcache entries will exist at process exit time it |
2205 | * just makes it very unlikely that any will persist. | 2206 | * just makes it very unlikely that any will persist. |
2206 | */ | 2207 | */ |
2207 | void proc_flush_task(struct task_struct *task) | 2208 | static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid) |
2208 | { | 2209 | { |
2209 | struct dentry *dentry, *leader, *dir; | 2210 | struct dentry *dentry, *leader, *dir; |
2210 | char buf[PROC_NUMBUF]; | 2211 | char buf[PROC_NUMBUF]; |
2211 | struct qstr name; | 2212 | struct qstr name; |
2212 | 2213 | ||
2213 | name.name = buf; | 2214 | name.name = buf; |
2214 | name.len = snprintf(buf, sizeof(buf), "%d", task->pid); | 2215 | name.len = snprintf(buf, sizeof(buf), "%d", pid); |
2215 | dentry = d_hash_and_lookup(proc_mnt->mnt_root, &name); | 2216 | dentry = d_hash_and_lookup(mnt->mnt_root, &name); |
2216 | if (dentry) { | 2217 | if (dentry) { |
2217 | shrink_dcache_parent(dentry); | 2218 | shrink_dcache_parent(dentry); |
2218 | d_drop(dentry); | 2219 | d_drop(dentry); |
2219 | dput(dentry); | 2220 | dput(dentry); |
2220 | } | 2221 | } |
2221 | 2222 | ||
2222 | if (thread_group_leader(task)) | 2223 | if (tgid == 0) |
2223 | goto out; | 2224 | goto out; |
2224 | 2225 | ||
2225 | name.name = buf; | 2226 | name.name = buf; |
2226 | name.len = snprintf(buf, sizeof(buf), "%d", task->tgid); | 2227 | name.len = snprintf(buf, sizeof(buf), "%d", tgid); |
2227 | leader = d_hash_and_lookup(proc_mnt->mnt_root, &name); | 2228 | leader = d_hash_and_lookup(mnt->mnt_root, &name); |
2228 | if (!leader) | 2229 | if (!leader) |
2229 | goto out; | 2230 | goto out; |
2230 | 2231 | ||
@@ -2235,7 +2236,7 @@ void proc_flush_task(struct task_struct *task) | |||
2235 | goto out_put_leader; | 2236 | goto out_put_leader; |
2236 | 2237 | ||
2237 | name.name = buf; | 2238 | name.name = buf; |
2238 | name.len = snprintf(buf, sizeof(buf), "%d", task->pid); | 2239 | name.len = snprintf(buf, sizeof(buf), "%d", pid); |
2239 | dentry = d_hash_and_lookup(dir, &name); | 2240 | dentry = d_hash_and_lookup(dir, &name); |
2240 | if (dentry) { | 2241 | if (dentry) { |
2241 | shrink_dcache_parent(dentry); | 2242 | shrink_dcache_parent(dentry); |
@@ -2250,6 +2251,18 @@ out: | |||
2250 | return; | 2251 | return; |
2251 | } | 2252 | } |
2252 | 2253 | ||
2254 | /* | ||
2255 | * when flushing dentries from proc one need to flush them from global | ||
2256 | * proc (proc_mnt) and from all the namespaces' procs this task was seen | ||
2257 | * in. this call is supposed to make all this job. | ||
2258 | */ | ||
2259 | |||
2260 | void proc_flush_task(struct task_struct *task) | ||
2261 | { | ||
2262 | proc_flush_task_mnt(proc_mnt, task->pid, | ||
2263 | thread_group_leader(task) ? 0 : task->tgid); | ||
2264 | } | ||
2265 | |||
2253 | static struct dentry *proc_pid_instantiate(struct inode *dir, | 2266 | static struct dentry *proc_pid_instantiate(struct inode *dir, |
2254 | struct dentry * dentry, | 2267 | struct dentry * dentry, |
2255 | struct task_struct *task, const void *ptr) | 2268 | struct task_struct *task, const void *ptr) |