public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Tejun Heo <tj@kernel.org>
To: gregkh@linuxfoundation.org
Cc: linux-kernel@vger.kernel.org, Tejun Heo <tj@kernel.org>
Subject: [PATCH 01/10] kernfs: invoke dir_ops while holding active ref of the target node
Date: Mon,  3 Feb 2014 14:09:08 -0500	[thread overview]
Message-ID: <1391454557-32376-2-git-send-email-tj@kernel.org> (raw)
In-Reply-To: <1391454557-32376-1-git-send-email-tj@kernel.org>

kernfs_dir_ops are currently being invoked without any active
reference, which makes it tricky for the invoked operations to
determine whether the objects associated those nodes are safe to
access and will remain that way for the duration of such operations.

kernfs already has active_ref mechanism to deal with this which makes
the removal of a given node the synchronization point for gating the
file operations.  There's no reason for dir_ops to be any different.
Update the dir_ops handling so that active_ref is held while the
dir_ops are executing.  This guarantees that while a dir_ops is
executing the target nodes stay alive.

As kernfs_dir_ops doesn't have any in-kernel user at this point, this
doesn't affect anybody.

Signed-off-by: Tejun Heo <tj@kernel.org>
---
 fs/kernfs/dir.c        | 33 ++++++++++++++++++++++++++++++---
 include/linux/kernfs.h |  3 ++-
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index 8c63ae1..bfbfb48 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -654,22 +654,36 @@ static int kernfs_iop_mkdir(struct inode *dir, struct dentry *dentry,
 {
 	struct kernfs_node *parent = dir->i_private;
 	struct kernfs_dir_ops *kdops = kernfs_root(parent)->dir_ops;
+	int ret;
 
 	if (!kdops || !kdops->mkdir)
 		return -EPERM;
 
-	return kdops->mkdir(parent, dentry->d_name.name, mode);
+	if (!kernfs_get_active(parent))
+		return -ENODEV;
+
+	ret = kdops->mkdir(parent, dentry->d_name.name, mode);
+
+	kernfs_put_active(parent);
+	return ret;
 }
 
 static int kernfs_iop_rmdir(struct inode *dir, struct dentry *dentry)
 {
 	struct kernfs_node *kn  = dentry->d_fsdata;
 	struct kernfs_dir_ops *kdops = kernfs_root(kn)->dir_ops;
+	int ret;
 
 	if (!kdops || !kdops->rmdir)
 		return -EPERM;
 
-	return kdops->rmdir(kn);
+	if (!kernfs_get_active(kn))
+		return -ENODEV;
+
+	ret = kdops->rmdir(kn);
+
+	kernfs_put_active(kn);
+	return ret;
 }
 
 static int kernfs_iop_rename(struct inode *old_dir, struct dentry *old_dentry,
@@ -678,11 +692,24 @@ static int kernfs_iop_rename(struct inode *old_dir, struct dentry *old_dentry,
 	struct kernfs_node *kn  = old_dentry->d_fsdata;
 	struct kernfs_node *new_parent = new_dir->i_private;
 	struct kernfs_dir_ops *kdops = kernfs_root(kn)->dir_ops;
+	int ret;
 
 	if (!kdops || !kdops->rename)
 		return -EPERM;
 
-	return kdops->rename(kn, new_parent, new_dentry->d_name.name);
+	if (!kernfs_get_active(kn))
+		return -ENODEV;
+
+	if (!kernfs_get_active(new_parent)) {
+		kernfs_put_active(kn);
+		return -ENODEV;
+	}
+
+	ret = kdops->rename(kn, new_parent, new_dentry->d_name.name);
+
+	kernfs_put_active(new_parent);
+	kernfs_put_active(kn);
+	return ret;
 }
 
 const struct inode_operations kernfs_dir_iops = {
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 02ac334..58a131d 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -111,7 +111,8 @@ struct kernfs_node {
  * kernfs_dir_ops may be specified on kernfs_create_root() to support
  * directory manipulation syscalls.  These optional callbacks are invoked
  * on the matching syscalls and can perform any kernfs operations which
- * don't necessarily have to be the exact operation requested.
+ * don't necessarily have to be the exact operation requested.  An active
+ * reference is held for each kernfs_node parameter.
  */
 struct kernfs_dir_ops {
 	int (*mkdir)(struct kernfs_node *parent, const char *name,
-- 
1.8.5.3


  reply	other threads:[~2014-02-03 19:12 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-03 19:09 [PATCHSET v2 driver-core-next] kernfs: prepare for cgroup's kernfs conversion Tejun Heo
2014-02-03 19:09 ` Tejun Heo [this message]
2014-02-03 19:09 ` [PATCH 02/10] kernfs: rename kernfs_dir_ops to kernfs_syscall_ops Tejun Heo
2014-02-03 19:09 ` [PATCH 03/10] kernfs: implement kernfs_syscall_ops->remount_fs() and ->show_options() Tejun Heo
2014-02-03 19:09 ` [PATCH 04/10] kernfs: add missing kernfs_active() checks in directory operations Tejun Heo
2014-02-03 19:09 ` [PATCH 05/10] kernfs: allow nodes to be created in the deactivated state Tejun Heo
2014-02-03 19:09 ` [PATCH 06/10] kernfs: implement kernfs_ops->atomic_write_len Tejun Heo
2014-02-03 19:09 ` [PATCH 07/10] kernfs: add kernfs_open_file->priv Tejun Heo
2014-02-03 19:09 ` [PATCH 08/10] kernfs: implement kernfs_node_from_dentry(), kernfs_root_from_sb() and kernfs_rename() Tejun Heo
2014-02-03 19:09 ` [PATCH 09/10] kernfs: implement kernfs_get_parent(), kernfs_name/path() and friends Tejun Heo
2014-02-07 18:40   ` [PATCH v2 " Tejun Heo
2014-02-03 19:09 ` [PATCH 10/10] kernfs: add CONFIG_KERNFS Tejun Heo
2014-02-07 18:41 ` [PATCH 9.5/10] sysfs, kobject: add sysfs wrapper for kernfs_enable_ns() Tejun Heo
2014-02-07 18:43 ` [PATCHSET v2 driver-core-next] kernfs: prepare for cgroup's kernfs conversion Tejun Heo
2014-02-08  0:12   ` Greg KH
2014-02-08 15:07     ` Tejun Heo
2014-02-08 15:08       ` Tejun Heo
2014-02-08 18:17         ` Greg KH
2014-02-08 18:17           ` Tejun Heo

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=1391454557-32376-2-git-send-email-tj@kernel.org \
    --to=tj@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    /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