aboutsummaryrefslogtreecommitdiff
path: root/include/linux/kernfs.h
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-12-11 16:03:00 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-12-17 08:59:15 -0800
commit80b9bbefc345079bddc4959de016ba4074b0c8d6 (patch)
tree24d24636b01d9f9e31b39e08a8cfd0978ce9fd9d /include/linux/kernfs.h
parent19bbb926203dbcf3a03915e934c36d7681bf6e13 (diff)
kernfs: add kernfs_dir_ops
Add support for mkdir(2), rmdir(2) and rename(2) syscalls. This is implemented through optional kernfs_dir_ops callback table which can be specified on kernfs_create_root(). An implemented callback is invoked when the matching syscall is invoked. As kernfs keep dcache syncs with internal representation and revalidates dentries on each access, the implementation of these methods is extremely simple. Each just discovers the relevant kernfs_node(s) and invokes the requested callback which is allowed to do any kernfs operations and the end result doesn't necessarily have to match the expected semantics of the syscall. This will be used to convert cgroup to use kernfs instead of its own filesystem implementation. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/linux/kernfs.h')
-rw-r--r--include/linux/kernfs.h21
1 files changed, 19 insertions, 2 deletions
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 321ed84ad4c..d2c439db4ef 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -111,12 +111,27 @@ struct kernfs_node {
struct kernfs_iattrs *iattr;
};
+/*
+ * 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.
+ */
+struct kernfs_dir_ops {
+ int (*mkdir)(struct kernfs_node *parent, const char *name,
+ umode_t mode);
+ int (*rmdir)(struct kernfs_node *kn);
+ int (*rename)(struct kernfs_node *kn, struct kernfs_node *new_parent,
+ const char *new_name);
+};
+
struct kernfs_root {
/* published fields */
struct kernfs_node *kn;
/* private fields, do not use outside kernfs proper */
struct ida ino_ida;
+ struct kernfs_dir_ops *dir_ops;
};
struct kernfs_open_file {
@@ -206,7 +221,8 @@ struct kernfs_node *kernfs_find_and_get_ns(struct kernfs_node *parent,
void kernfs_get(struct kernfs_node *kn);
void kernfs_put(struct kernfs_node *kn);
-struct kernfs_root *kernfs_create_root(void *priv);
+struct kernfs_root *kernfs_create_root(struct kernfs_dir_ops *kdops,
+ void *priv);
void kernfs_destroy_root(struct kernfs_root *root);
struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent,
@@ -255,7 +271,8 @@ kernfs_find_and_get_ns(struct kernfs_node *parent, const char *name,
static inline void kernfs_get(struct kernfs_node *kn) { }
static inline void kernfs_put(struct kernfs_node *kn) { }
-static inline struct kernfs_root *kernfs_create_root(void *priv)
+static inline struct kernfs_root *
+kernfs_create_root(struct kernfs_dir_ops *kdops, void *priv)
{ return ERR_PTR(-ENOSYS); }
static inline void kernfs_destroy_root(struct kernfs_root *root) { }