2013-11-24 22:54:58 +08:00
|
|
|
/*
|
|
|
|
* kernfs.h - pseudo filesystem decoupled from vfs locking
|
|
|
|
*
|
|
|
|
* This file is released under the GPLv2.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __LINUX_KERNFS_H
|
|
|
|
#define __LINUX_KERNFS_H
|
|
|
|
|
2013-11-24 06:21:49 +08:00
|
|
|
#include <linux/kernel.h>
|
2013-11-24 06:21:50 +08:00
|
|
|
#include <linux/err.h>
|
2013-11-29 03:54:20 +08:00
|
|
|
#include <linux/list.h>
|
|
|
|
#include <linux/mutex.h>
|
2013-11-29 03:54:41 +08:00
|
|
|
#include <linux/idr.h>
|
2013-11-29 03:54:29 +08:00
|
|
|
#include <linux/lockdep.h>
|
2013-11-30 06:18:32 +08:00
|
|
|
#include <linux/rbtree.h>
|
|
|
|
#include <linux/atomic.h>
|
2014-01-10 21:57:19 +08:00
|
|
|
#include <linux/wait.h>
|
2013-11-24 06:21:49 +08:00
|
|
|
|
2013-11-24 06:21:52 +08:00
|
|
|
struct file;
|
|
|
|
struct iattr;
|
2013-11-29 03:54:20 +08:00
|
|
|
struct seq_file;
|
|
|
|
struct vm_area_struct;
|
2013-11-29 03:54:43 +08:00
|
|
|
struct super_block;
|
|
|
|
struct file_system_type;
|
2013-11-24 06:21:52 +08:00
|
|
|
|
2013-12-12 03:11:55 +08:00
|
|
|
struct kernfs_open_node;
|
|
|
|
struct kernfs_iattrs;
|
2013-11-30 06:18:32 +08:00
|
|
|
|
|
|
|
enum kernfs_node_type {
|
2013-12-12 03:11:56 +08:00
|
|
|
KERNFS_DIR = 0x0001,
|
|
|
|
KERNFS_FILE = 0x0002,
|
|
|
|
KERNFS_LINK = 0x0004,
|
2013-11-30 06:18:32 +08:00
|
|
|
};
|
|
|
|
|
2013-12-12 03:11:56 +08:00
|
|
|
#define KERNFS_TYPE_MASK 0x000f
|
|
|
|
#define KERNFS_FLAG_MASK ~KERNFS_TYPE_MASK
|
2013-11-30 06:18:32 +08:00
|
|
|
|
|
|
|
enum kernfs_node_flag {
|
kernfs: restructure removal path to fix possible premature return
The recursive nature of kernfs_remove() means that, even if
kernfs_remove() is not allowed to be called multiple times on the same
node, there may be race conditions between removal of parent and its
descendants. While we can claim that kernfs_remove() shouldn't be
called on one of the descendants while the removal of an ancestor is
in progress, such rule is unnecessarily restrictive and very difficult
to enforce. It's better to simply allow invoking kernfs_remove() as
the caller sees fit as long as the caller ensures that the node is
accessible.
The current behavior in such situations is broken. Whoever enters
removal path first takes the node off the hierarchy and then
deactivates. Following removers either return as soon as it notices
that it's not the first one or can't even find the target node as it
has already been removed from the hierarchy. In both cases, the
following removers may finish prematurely while the nodes which should
be removed and drained are still being processed by the first one.
This patch restructures so that multiple removers, whether through
recursion or direction invocation, always follow the following rules.
* When there are multiple concurrent removers, only one puts the base
ref.
* Regardless of which one puts the base ref, all removers are blocked
until the target node is fully deactivated and removed.
To achieve the above, removal path now first deactivates the subtree,
drains it and then unlinks one-by-one. __kernfs_deactivate() is
called directly from __kernfs_removal() and drops and regrabs
kernfs_mutex for each descendant to drain active refs. As this means
that multiple removers can enter __kernfs_deactivate() for the same
node, the function is updated so that it can handle multiple
deactivators of the same node - only one actually deactivates but all
wait till drain completion.
The restructured removal path guarantees that a removed node gets
unlinked only after the node is deactivated and drained. Combined
with proper multiple deactivator handling, this guarantees that any
invocation of kernfs_remove() returns only after the node itself and
all its descendants are deactivated, drained and removed.
v2: Draining separated into a separate loop (used to be in the same
loop as unlink) and done from __kernfs_deactivate(). This is to
allow exposing deactivation as a separate interface later.
Root node removal was broken in v1 patch. Fixed.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-01-10 21:57:22 +08:00
|
|
|
KERNFS_JUST_DEACTIVATED = 0x0010, /* used to aid lockdep annotation */
|
2013-12-12 03:11:56 +08:00
|
|
|
KERNFS_NS = 0x0020,
|
|
|
|
KERNFS_HAS_SEQ_SHOW = 0x0040,
|
|
|
|
KERNFS_HAS_MMAP = 0x0080,
|
|
|
|
KERNFS_LOCKDEP = 0x0100,
|
2013-12-12 05:02:57 +08:00
|
|
|
KERNFS_STATIC_NAME = 0x0200,
|
2013-11-30 06:18:32 +08:00
|
|
|
};
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
/* type-specific structures for kernfs_node union members */
|
|
|
|
struct kernfs_elem_dir {
|
2013-11-30 06:18:32 +08:00
|
|
|
unsigned long subdirs;
|
2013-12-12 03:11:54 +08:00
|
|
|
/* children rbtree starts here and goes through kn->rb */
|
2013-11-30 06:18:32 +08:00
|
|
|
struct rb_root children;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The kernfs hierarchy this directory belongs to. This fits
|
2013-12-12 03:11:53 +08:00
|
|
|
* better directly in kernfs_node but is here to save space.
|
2013-11-30 06:18:32 +08:00
|
|
|
*/
|
|
|
|
struct kernfs_root *root;
|
|
|
|
};
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
struct kernfs_elem_symlink {
|
|
|
|
struct kernfs_node *target_kn;
|
2013-11-30 06:18:32 +08:00
|
|
|
};
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
struct kernfs_elem_attr {
|
2013-11-30 06:18:32 +08:00
|
|
|
const struct kernfs_ops *ops;
|
2013-12-12 03:11:55 +08:00
|
|
|
struct kernfs_open_node *open;
|
2013-11-30 06:18:32 +08:00
|
|
|
loff_t size;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
2013-12-12 03:11:53 +08:00
|
|
|
* kernfs_node - the building block of kernfs hierarchy. Each and every
|
|
|
|
* kernfs node is represented by single kernfs_node. Most fields are
|
2013-11-30 06:18:32 +08:00
|
|
|
* private to kernfs and shouldn't be accessed directly by kernfs users.
|
|
|
|
*
|
2013-12-12 03:11:53 +08:00
|
|
|
* As long as s_count reference is held, the kernfs_node itself is
|
|
|
|
* accessible. Dereferencing elem or any other outer entity requires
|
|
|
|
* active reference.
|
2013-11-30 06:18:32 +08:00
|
|
|
*/
|
2013-12-12 03:11:53 +08:00
|
|
|
struct kernfs_node {
|
2013-12-12 03:11:54 +08:00
|
|
|
atomic_t count;
|
|
|
|
atomic_t active;
|
2014-01-10 21:57:26 +08:00
|
|
|
int deact_depth;
|
|
|
|
unsigned int hash; /* ns + name hash */
|
2013-11-30 06:18:32 +08:00
|
|
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
|
|
|
struct lockdep_map dep_map;
|
|
|
|
#endif
|
|
|
|
/* the following two fields are published */
|
2013-12-12 03:11:54 +08:00
|
|
|
struct kernfs_node *parent;
|
|
|
|
const char *name;
|
2013-11-30 06:18:32 +08:00
|
|
|
|
2013-12-12 03:11:54 +08:00
|
|
|
struct rb_node rb;
|
2013-11-30 06:18:32 +08:00
|
|
|
|
2013-12-12 03:11:54 +08:00
|
|
|
const void *ns; /* namespace tag */
|
2013-11-30 06:18:32 +08:00
|
|
|
union {
|
2013-12-12 03:11:54 +08:00
|
|
|
struct kernfs_elem_dir dir;
|
|
|
|
struct kernfs_elem_symlink symlink;
|
|
|
|
struct kernfs_elem_attr attr;
|
2013-11-30 06:18:32 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
void *priv;
|
|
|
|
|
2013-12-12 03:11:54 +08:00
|
|
|
unsigned short flags;
|
|
|
|
umode_t mode;
|
|
|
|
unsigned int ino;
|
2013-12-12 03:11:55 +08:00
|
|
|
struct kernfs_iattrs *iattr;
|
2013-11-30 06:18:32 +08:00
|
|
|
};
|
2013-11-24 22:54:58 +08:00
|
|
|
|
2013-12-12 05:03:00 +08:00
|
|
|
/*
|
|
|
|
* 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);
|
|
|
|
};
|
|
|
|
|
2013-11-29 03:54:40 +08:00
|
|
|
struct kernfs_root {
|
|
|
|
/* published fields */
|
2013-12-12 03:11:53 +08:00
|
|
|
struct kernfs_node *kn;
|
2013-11-29 03:54:41 +08:00
|
|
|
|
|
|
|
/* private fields, do not use outside kernfs proper */
|
|
|
|
struct ida ino_ida;
|
2013-12-12 05:03:00 +08:00
|
|
|
struct kernfs_dir_ops *dir_ops;
|
2014-01-10 21:57:19 +08:00
|
|
|
wait_queue_head_t deactivate_waitq;
|
2013-11-29 03:54:40 +08:00
|
|
|
};
|
|
|
|
|
2013-12-12 03:11:55 +08:00
|
|
|
struct kernfs_open_file {
|
2013-11-29 03:54:20 +08:00
|
|
|
/* published fields */
|
2013-12-12 03:11:53 +08:00
|
|
|
struct kernfs_node *kn;
|
2013-11-29 03:54:20 +08:00
|
|
|
struct file *file;
|
|
|
|
|
|
|
|
/* private fields, do not use outside kernfs proper */
|
|
|
|
struct mutex mutex;
|
|
|
|
int event;
|
|
|
|
struct list_head list;
|
|
|
|
|
|
|
|
bool mmapped;
|
|
|
|
const struct vm_operations_struct *vm_ops;
|
|
|
|
};
|
|
|
|
|
2013-11-29 03:54:21 +08:00
|
|
|
struct kernfs_ops {
|
|
|
|
/*
|
|
|
|
* Read is handled by either seq_file or raw_read().
|
|
|
|
*
|
2013-11-29 03:54:26 +08:00
|
|
|
* If seq_show() is present, seq_file path is active. Other seq
|
|
|
|
* operations are optional and if not implemented, the behavior is
|
|
|
|
* equivalent to single_open(). @sf->private points to the
|
2013-12-12 03:11:55 +08:00
|
|
|
* associated kernfs_open_file.
|
2013-11-29 03:54:21 +08:00
|
|
|
*
|
|
|
|
* read() is bounced through kernel buffer and a read larger than
|
|
|
|
* PAGE_SIZE results in partial operation of PAGE_SIZE.
|
|
|
|
*/
|
|
|
|
int (*seq_show)(struct seq_file *sf, void *v);
|
2013-11-29 03:54:26 +08:00
|
|
|
|
|
|
|
void *(*seq_start)(struct seq_file *sf, loff_t *ppos);
|
|
|
|
void *(*seq_next)(struct seq_file *sf, void *v, loff_t *ppos);
|
|
|
|
void (*seq_stop)(struct seq_file *sf, void *v);
|
2013-11-29 03:54:21 +08:00
|
|
|
|
2013-12-12 03:11:55 +08:00
|
|
|
ssize_t (*read)(struct kernfs_open_file *of, char *buf, size_t bytes,
|
2013-11-29 03:54:21 +08:00
|
|
|
loff_t off);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* write() is bounced through kernel buffer and a write larger than
|
|
|
|
* PAGE_SIZE results in partial operation of PAGE_SIZE.
|
|
|
|
*/
|
2013-12-12 03:11:55 +08:00
|
|
|
ssize_t (*write)(struct kernfs_open_file *of, char *buf, size_t bytes,
|
2013-11-29 03:54:21 +08:00
|
|
|
loff_t off);
|
|
|
|
|
2013-12-12 03:11:55 +08:00
|
|
|
int (*mmap)(struct kernfs_open_file *of, struct vm_area_struct *vma);
|
2013-11-29 03:54:29 +08:00
|
|
|
|
|
|
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
|
|
|
struct lock_class_key lockdep_key;
|
|
|
|
#endif
|
2013-11-29 03:54:21 +08:00
|
|
|
};
|
|
|
|
|
2013-11-24 06:21:49 +08:00
|
|
|
#ifdef CONFIG_SYSFS
|
|
|
|
|
2013-12-12 03:11:56 +08:00
|
|
|
static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn)
|
2013-11-30 06:18:32 +08:00
|
|
|
{
|
2013-12-12 03:11:56 +08:00
|
|
|
return kn->flags & KERNFS_TYPE_MASK;
|
2013-11-30 06:18:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* kernfs_enable_ns - enable namespace under a directory
|
2013-12-12 03:11:53 +08:00
|
|
|
* @kn: directory of interest, should be empty
|
2013-11-30 06:18:32 +08:00
|
|
|
*
|
2013-12-12 03:11:53 +08:00
|
|
|
* This is to be called right after @kn is created to enable namespace
|
|
|
|
* under it. All children of @kn must have non-NULL namespace tags and
|
2013-11-30 06:18:32 +08:00
|
|
|
* only the ones which match the super_block's tag will be visible.
|
|
|
|
*/
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline void kernfs_enable_ns(struct kernfs_node *kn)
|
2013-11-30 06:18:32 +08:00
|
|
|
{
|
2013-12-12 03:11:56 +08:00
|
|
|
WARN_ON_ONCE(kernfs_type(kn) != KERNFS_DIR);
|
2013-12-12 03:11:54 +08:00
|
|
|
WARN_ON_ONCE(!RB_EMPTY_ROOT(&kn->dir.children));
|
2013-12-12 03:11:56 +08:00
|
|
|
kn->flags |= KERNFS_NS;
|
2013-11-30 06:18:32 +08:00
|
|
|
}
|
|
|
|
|
2013-11-30 06:19:09 +08:00
|
|
|
/**
|
|
|
|
* kernfs_ns_enabled - test whether namespace is enabled
|
2013-12-12 03:11:53 +08:00
|
|
|
* @kn: the node to test
|
2013-11-30 06:19:09 +08:00
|
|
|
*
|
|
|
|
* Test whether namespace filtering is enabled for the children of @ns.
|
|
|
|
*/
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline bool kernfs_ns_enabled(struct kernfs_node *kn)
|
2013-11-30 06:19:09 +08:00
|
|
|
{
|
2013-12-12 03:11:56 +08:00
|
|
|
return kn->flags & KERNFS_NS;
|
2013-11-30 06:19:09 +08:00
|
|
|
}
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
struct kernfs_node *kernfs_find_and_get_ns(struct kernfs_node *parent,
|
|
|
|
const char *name, const void *ns);
|
|
|
|
void kernfs_get(struct kernfs_node *kn);
|
|
|
|
void kernfs_put(struct kernfs_node *kn);
|
2013-11-29 03:54:30 +08:00
|
|
|
|
2013-12-12 05:03:00 +08:00
|
|
|
struct kernfs_root *kernfs_create_root(struct kernfs_dir_ops *kdops,
|
|
|
|
void *priv);
|
2013-11-29 03:54:40 +08:00
|
|
|
void kernfs_destroy_root(struct kernfs_root *root);
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent,
|
2013-12-12 05:02:55 +08:00
|
|
|
const char *name, umode_t mode,
|
|
|
|
void *priv, const void *ns);
|
2013-12-12 05:02:57 +08:00
|
|
|
struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent,
|
|
|
|
const char *name,
|
|
|
|
umode_t mode, loff_t size,
|
|
|
|
const struct kernfs_ops *ops,
|
|
|
|
void *priv, const void *ns,
|
|
|
|
bool name_is_static,
|
|
|
|
struct lock_class_key *key);
|
2013-12-12 03:11:53 +08:00
|
|
|
struct kernfs_node *kernfs_create_link(struct kernfs_node *parent,
|
|
|
|
const char *name,
|
|
|
|
struct kernfs_node *target);
|
2014-01-10 21:57:26 +08:00
|
|
|
void kernfs_deactivate(struct kernfs_node *kn);
|
|
|
|
void kernfs_reactivate(struct kernfs_node *kn);
|
|
|
|
void kernfs_deactivate_self(struct kernfs_node *kn);
|
|
|
|
void kernfs_reactivate_self(struct kernfs_node *kn);
|
2013-12-12 03:11:53 +08:00
|
|
|
void kernfs_remove(struct kernfs_node *kn);
|
|
|
|
int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name,
|
2013-11-24 06:21:49 +08:00
|
|
|
const void *ns);
|
2013-12-12 03:11:53 +08:00
|
|
|
int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
|
2013-11-24 06:21:51 +08:00
|
|
|
const char *new_name, const void *new_ns);
|
2013-12-12 03:11:53 +08:00
|
|
|
int kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr);
|
|
|
|
void kernfs_notify(struct kernfs_node *kn);
|
2013-11-24 06:21:49 +08:00
|
|
|
|
2013-11-29 03:54:43 +08:00
|
|
|
const void *kernfs_super_ns(struct super_block *sb);
|
|
|
|
struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags,
|
|
|
|
struct kernfs_root *root, const void *ns);
|
|
|
|
void kernfs_kill_sb(struct super_block *sb);
|
|
|
|
|
|
|
|
void kernfs_init(void);
|
|
|
|
|
2013-11-24 06:21:49 +08:00
|
|
|
#else /* CONFIG_SYSFS */
|
|
|
|
|
2013-12-12 03:11:56 +08:00
|
|
|
static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn)
|
2013-11-30 06:18:32 +08:00
|
|
|
{ return 0; } /* whatever */
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline void kernfs_enable_ns(struct kernfs_node *kn) { }
|
2013-11-30 06:18:32 +08:00
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline bool kernfs_ns_enabled(struct kernfs_node *kn)
|
2013-11-30 06:19:09 +08:00
|
|
|
{ return false; }
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline struct kernfs_node *
|
|
|
|
kernfs_find_and_get_ns(struct kernfs_node *parent, const char *name,
|
2013-11-29 03:54:30 +08:00
|
|
|
const void *ns)
|
|
|
|
{ return NULL; }
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline void kernfs_get(struct kernfs_node *kn) { }
|
|
|
|
static inline void kernfs_put(struct kernfs_node *kn) { }
|
2013-11-29 03:54:30 +08:00
|
|
|
|
2013-12-12 05:03:00 +08:00
|
|
|
static inline struct kernfs_root *
|
|
|
|
kernfs_create_root(struct kernfs_dir_ops *kdops, void *priv)
|
2013-11-29 03:54:40 +08:00
|
|
|
{ return ERR_PTR(-ENOSYS); }
|
|
|
|
|
|
|
|
static inline void kernfs_destroy_root(struct kernfs_root *root) { }
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline struct kernfs_node *
|
2013-12-12 05:02:55 +08:00
|
|
|
kernfs_create_dir_ns(struct kernfs_node *parent, const char *name,
|
|
|
|
umode_t mode, void *priv, const void *ns)
|
2013-11-29 03:54:15 +08:00
|
|
|
{ return ERR_PTR(-ENOSYS); }
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline struct kernfs_node *
|
2013-12-12 05:02:57 +08:00
|
|
|
__kernfs_create_file(struct kernfs_node *parent, const char *name,
|
|
|
|
umode_t mode, loff_t size, const struct kernfs_ops *ops,
|
|
|
|
void *priv, const void *ns, bool name_is_static,
|
|
|
|
struct lock_class_key *key)
|
2013-11-29 03:54:24 +08:00
|
|
|
{ return ERR_PTR(-ENOSYS); }
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline struct kernfs_node *
|
|
|
|
kernfs_create_link(struct kernfs_node *parent, const char *name,
|
|
|
|
struct kernfs_node *target)
|
2013-11-24 06:21:50 +08:00
|
|
|
{ return ERR_PTR(-ENOSYS); }
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline void kernfs_remove(struct kernfs_node *kn) { }
|
2013-11-24 06:21:49 +08:00
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline int kernfs_remove_by_name_ns(struct kernfs_node *kn,
|
2013-11-24 06:21:49 +08:00
|
|
|
const char *name, const void *ns)
|
|
|
|
{ return -ENOSYS; }
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline int kernfs_rename_ns(struct kernfs_node *kn,
|
|
|
|
struct kernfs_node *new_parent,
|
2013-11-24 06:21:51 +08:00
|
|
|
const char *new_name, const void *new_ns)
|
|
|
|
{ return -ENOSYS; }
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline int kernfs_setattr(struct kernfs_node *kn,
|
2013-11-24 06:21:52 +08:00
|
|
|
const struct iattr *iattr)
|
|
|
|
{ return -ENOSYS; }
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline void kernfs_notify(struct kernfs_node *kn) { }
|
2013-11-29 03:54:27 +08:00
|
|
|
|
2013-11-29 03:54:43 +08:00
|
|
|
static inline const void *kernfs_super_ns(struct super_block *sb)
|
|
|
|
{ return NULL; }
|
|
|
|
|
|
|
|
static inline struct dentry *
|
|
|
|
kernfs_mount_ns(struct file_system_type *fs_type, int flags,
|
|
|
|
struct kernfs_root *root, const void *ns)
|
|
|
|
{ return ERR_PTR(-ENOSYS); }
|
|
|
|
|
|
|
|
static inline void kernfs_kill_sb(struct super_block *sb) { }
|
|
|
|
|
|
|
|
static inline void kernfs_init(void) { }
|
|
|
|
|
2013-11-24 06:21:49 +08:00
|
|
|
#endif /* CONFIG_SYSFS */
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline struct kernfs_node *
|
|
|
|
kernfs_find_and_get(struct kernfs_node *kn, const char *name)
|
2013-11-29 03:54:30 +08:00
|
|
|
{
|
2013-12-12 03:11:53 +08:00
|
|
|
return kernfs_find_and_get_ns(kn, name, NULL);
|
2013-11-29 03:54:30 +08:00
|
|
|
}
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline struct kernfs_node *
|
2013-12-12 05:02:55 +08:00
|
|
|
kernfs_create_dir(struct kernfs_node *parent, const char *name, umode_t mode,
|
|
|
|
void *priv)
|
2013-11-29 03:54:15 +08:00
|
|
|
{
|
2013-12-12 05:02:55 +08:00
|
|
|
return kernfs_create_dir_ns(parent, name, mode, priv, NULL);
|
2013-11-29 03:54:15 +08:00
|
|
|
}
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline struct kernfs_node *
|
|
|
|
kernfs_create_file_ns(struct kernfs_node *parent, const char *name,
|
2013-11-29 03:54:29 +08:00
|
|
|
umode_t mode, loff_t size, const struct kernfs_ops *ops,
|
|
|
|
void *priv, const void *ns)
|
|
|
|
{
|
|
|
|
struct lock_class_key *key = NULL;
|
|
|
|
|
|
|
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
|
|
|
key = (struct lock_class_key *)&ops->lockdep_key;
|
|
|
|
#endif
|
2013-12-12 05:02:57 +08:00
|
|
|
return __kernfs_create_file(parent, name, mode, size, ops, priv, ns,
|
|
|
|
false, key);
|
2013-11-29 03:54:29 +08:00
|
|
|
}
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline struct kernfs_node *
|
|
|
|
kernfs_create_file(struct kernfs_node *parent, const char *name, umode_t mode,
|
2013-11-29 03:54:24 +08:00
|
|
|
loff_t size, const struct kernfs_ops *ops, void *priv)
|
|
|
|
{
|
|
|
|
return kernfs_create_file_ns(parent, name, mode, size, ops, priv, NULL);
|
|
|
|
}
|
|
|
|
|
2013-12-12 03:11:53 +08:00
|
|
|
static inline int kernfs_remove_by_name(struct kernfs_node *parent,
|
2013-11-24 06:21:49 +08:00
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
return kernfs_remove_by_name_ns(parent, name, NULL);
|
|
|
|
}
|
|
|
|
|
2013-11-29 03:54:43 +08:00
|
|
|
static inline struct dentry *
|
|
|
|
kernfs_mount(struct file_system_type *fs_type, int flags,
|
|
|
|
struct kernfs_root *root)
|
|
|
|
{
|
|
|
|
return kernfs_mount_ns(fs_type, flags, root, NULL);
|
|
|
|
}
|
|
|
|
|
2013-11-24 22:54:58 +08:00
|
|
|
#endif /* __LINUX_KERNFS_H */
|