|
@@ -74,6 +74,7 @@
|
|
|
#include <linux/nsproxy.h>
|
|
|
#include <linux/oom.h>
|
|
|
#include <linux/elf.h>
|
|
|
+#include <linux/pid_namespace.h>
|
|
|
#include "internal.h"
|
|
|
|
|
|
/* NOTE:
|
|
@@ -2204,27 +2205,27 @@ static const struct inode_operations proc_tgid_base_inode_operations = {
|
|
|
* that no dcache entries will exist at process exit time it
|
|
|
* just makes it very unlikely that any will persist.
|
|
|
*/
|
|
|
-void proc_flush_task(struct task_struct *task)
|
|
|
+static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
|
|
|
{
|
|
|
struct dentry *dentry, *leader, *dir;
|
|
|
char buf[PROC_NUMBUF];
|
|
|
struct qstr name;
|
|
|
|
|
|
name.name = buf;
|
|
|
- name.len = snprintf(buf, sizeof(buf), "%d", task->pid);
|
|
|
- dentry = d_hash_and_lookup(proc_mnt->mnt_root, &name);
|
|
|
+ name.len = snprintf(buf, sizeof(buf), "%d", pid);
|
|
|
+ dentry = d_hash_and_lookup(mnt->mnt_root, &name);
|
|
|
if (dentry) {
|
|
|
shrink_dcache_parent(dentry);
|
|
|
d_drop(dentry);
|
|
|
dput(dentry);
|
|
|
}
|
|
|
|
|
|
- if (thread_group_leader(task))
|
|
|
+ if (tgid == 0)
|
|
|
goto out;
|
|
|
|
|
|
name.name = buf;
|
|
|
- name.len = snprintf(buf, sizeof(buf), "%d", task->tgid);
|
|
|
- leader = d_hash_and_lookup(proc_mnt->mnt_root, &name);
|
|
|
+ name.len = snprintf(buf, sizeof(buf), "%d", tgid);
|
|
|
+ leader = d_hash_and_lookup(mnt->mnt_root, &name);
|
|
|
if (!leader)
|
|
|
goto out;
|
|
|
|
|
@@ -2235,7 +2236,7 @@ void proc_flush_task(struct task_struct *task)
|
|
|
goto out_put_leader;
|
|
|
|
|
|
name.name = buf;
|
|
|
- name.len = snprintf(buf, sizeof(buf), "%d", task->pid);
|
|
|
+ name.len = snprintf(buf, sizeof(buf), "%d", pid);
|
|
|
dentry = d_hash_and_lookup(dir, &name);
|
|
|
if (dentry) {
|
|
|
shrink_dcache_parent(dentry);
|
|
@@ -2250,6 +2251,18 @@ out:
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * when flushing dentries from proc one need to flush them from global
|
|
|
+ * proc (proc_mnt) and from all the namespaces' procs this task was seen
|
|
|
+ * in. this call is supposed to make all this job.
|
|
|
+ */
|
|
|
+
|
|
|
+void proc_flush_task(struct task_struct *task)
|
|
|
+{
|
|
|
+ proc_flush_task_mnt(proc_mnt, task->pid,
|
|
|
+ thread_group_leader(task) ? 0 : task->tgid);
|
|
|
+}
|
|
|
+
|
|
|
static struct dentry *proc_pid_instantiate(struct inode *dir,
|
|
|
struct dentry * dentry,
|
|
|
struct task_struct *task, const void *ptr)
|