mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Hou Tao <houtao1@huawei.com>
To: <linux-fsdevel@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Cc: <viro@zeniv.linux.org.uk>, <ebiederm@xmission.com>
Subject: [RFC][PATCH] proc: invalidate the deleting or deleted proc dentry
Date: Thu, 13 Apr 2017 21:49:35 +0800	[thread overview]
Message-ID: <1492091375-18642-1-git-send-email-houtao1@huawei.com> (raw)

After the invocation of remove_proc_entry() for a proc fs directory,
if the related dentry had been held by some processes (eg., by chdir),
the lookup afterwards will still return the old proc_dir_entry. The
new created proc fs files under the proc fs directory will not be
visible until the old dentry is released, and this makes our hotplug
process to fail which needs to access the new proc fs files.

To fix it, we need to mark the deleting or deleted proc_dir_entry
as invalid and the lookup afterwards will use the new proc_dir_entry
regardless of the status of the old dentry.

Signed-off-by: Hou Tao <houtao1@huawei.com>
---
 fs/proc/generic.c  | 21 ++++++++++++++++++++-
 fs/proc/inode.c    |  5 +++++
 fs/proc/internal.h |  1 +
 3 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index ee27feb..92c9dd4 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -23,11 +23,19 @@
 #include <linux/spinlock.h>
 #include <linux/completion.h>
 #include <linux/uaccess.h>
+#include <linux/namei.h>
 
 #include "internal.h"
 
+static int proc_dentry_revalidate(struct dentry *dentry, unsigned int flags);
+
 static DEFINE_RWLOCK(proc_subdir_lock);
 
+static const struct dentry_operations proc_dentry_operations = {
+	.d_revalidate = proc_dentry_revalidate,
+	.d_delete = always_delete_dentry,
+};
+
 static int proc_match(unsigned int len, const char *name, struct proc_dir_entry *de)
 {
 	if (len < de->namelen)
@@ -223,6 +231,17 @@ void proc_free_inum(unsigned int inum)
 	spin_unlock_irqrestore(&proc_inum_lock, flags);
 }
 
+static int proc_dentry_revalidate(struct dentry *dentry, unsigned int flags)
+{
+	struct proc_dir_entry *de;
+
+	if (flags & LOOKUP_RCU)
+		return -ECHILD;
+
+	de = PDE(d_inode(dentry));
+	return !proc_entry_is_removing(de);
+}
+
 /*
  * Don't create negative dentries here, return -ENOENT by hand
  * instead.
@@ -240,7 +259,7 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
 		inode = proc_get_inode(dir->i_sb, de);
 		if (!inode)
 			return ERR_PTR(-ENOMEM);
-		d_set_d_op(dentry, &simple_dentry_operations);
+		d_set_d_op(dentry, &proc_dentry_operations);
 		d_add(dentry, inode);
 		return NULL;
 	}
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 2cc7a80..84232d0 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -171,6 +171,11 @@ static void close_pdeo(struct proc_dir_entry *pde, struct pde_opener *pdeo)
 	}
 }
 
+bool proc_entry_is_removing(struct proc_dir_entry *de)
+{
+	return (atomic_read(&de->in_use) == BIAS);
+}
+
 void proc_entry_rundown(struct proc_dir_entry *de)
 {
 	DECLARE_COMPLETION_ONSTACK(c);
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index c5ae09b..646b3f6 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -205,6 +205,7 @@ void set_proc_pid_nlink(void);
 extern struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *);
 extern int proc_fill_super(struct super_block *, void *data, int flags);
 extern void proc_entry_rundown(struct proc_dir_entry *);
+extern bool proc_entry_is_removing(struct proc_dir_entry *de);
 
 /*
  * proc_namespaces.c
-- 
2.5.0

             reply	other threads:[~2017-04-13 13:49 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-13 13:49 Hou Tao [this message]
2017-04-23  9:50 ` Hou Tao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1492091375-18642-1-git-send-email-houtao1@huawei.com \
    --to=houtao1@huawei.com \
    --cc=ebiederm@xmission.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®