18493bac1a
commit e23f568aa63f64cd6b355094224cc9356c0f696b upstream.
When the 32bit ino wraps around, kernfs increments the generation
number to distinguish reused ino instances. The wrap-around detection
tests whether the allocated ino is lower than what the cursor but the
cursor is pointing to the next ino to allocate so the condition never
triggers.
Fix it by remembering the last ino and comparing against that.
Signed-off-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Fixes: 4a3ef68aca
("kernfs: implement i_generation")
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: stable@vger.kernel.org # v4.14+
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
558 lines
17 KiB
C
558 lines
17 KiB
C
/*
|
|
* kernfs.h - pseudo filesystem decoupled from vfs locking
|
|
*
|
|
* This file is released under the GPLv2.
|
|
*/
|
|
|
|
#ifndef __LINUX_KERNFS_H
|
|
#define __LINUX_KERNFS_H
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/err.h>
|
|
#include <linux/list.h>
|
|
#include <linux/mutex.h>
|
|
#include <linux/idr.h>
|
|
#include <linux/lockdep.h>
|
|
#include <linux/rbtree.h>
|
|
#include <linux/atomic.h>
|
|
#include <linux/uidgid.h>
|
|
#include <linux/wait.h>
|
|
|
|
struct file;
|
|
struct dentry;
|
|
struct iattr;
|
|
struct seq_file;
|
|
struct vm_area_struct;
|
|
struct super_block;
|
|
struct file_system_type;
|
|
|
|
struct kernfs_open_node;
|
|
struct kernfs_iattrs;
|
|
|
|
enum kernfs_node_type {
|
|
KERNFS_DIR = 0x0001,
|
|
KERNFS_FILE = 0x0002,
|
|
KERNFS_LINK = 0x0004,
|
|
};
|
|
|
|
#define KERNFS_TYPE_MASK 0x000f
|
|
#define KERNFS_FLAG_MASK ~KERNFS_TYPE_MASK
|
|
|
|
enum kernfs_node_flag {
|
|
KERNFS_ACTIVATED = 0x0010,
|
|
KERNFS_NS = 0x0020,
|
|
KERNFS_HAS_SEQ_SHOW = 0x0040,
|
|
KERNFS_HAS_MMAP = 0x0080,
|
|
KERNFS_LOCKDEP = 0x0100,
|
|
KERNFS_SUICIDAL = 0x0400,
|
|
KERNFS_SUICIDED = 0x0800,
|
|
KERNFS_EMPTY_DIR = 0x1000,
|
|
KERNFS_HAS_RELEASE = 0x2000,
|
|
};
|
|
|
|
/* @flags for kernfs_create_root() */
|
|
enum kernfs_root_flag {
|
|
/*
|
|
* kernfs_nodes are created in the deactivated state and invisible.
|
|
* They require explicit kernfs_activate() to become visible. This
|
|
* can be used to make related nodes become visible atomically
|
|
* after all nodes are created successfully.
|
|
*/
|
|
KERNFS_ROOT_CREATE_DEACTIVATED = 0x0001,
|
|
|
|
/*
|
|
* For regular flies, if the opener has CAP_DAC_OVERRIDE, open(2)
|
|
* succeeds regardless of the RW permissions. sysfs had an extra
|
|
* layer of enforcement where open(2) fails with -EACCES regardless
|
|
* of CAP_DAC_OVERRIDE if the permission doesn't have the
|
|
* respective read or write access at all (none of S_IRUGO or
|
|
* S_IWUGO) or the respective operation isn't implemented. The
|
|
* following flag enables that behavior.
|
|
*/
|
|
KERNFS_ROOT_EXTRA_OPEN_PERM_CHECK = 0x0002,
|
|
|
|
/*
|
|
* The filesystem supports exportfs operation, so userspace can use
|
|
* fhandle to access nodes of the fs.
|
|
*/
|
|
KERNFS_ROOT_SUPPORT_EXPORTOP = 0x0004,
|
|
};
|
|
|
|
/* type-specific structures for kernfs_node union members */
|
|
struct kernfs_elem_dir {
|
|
unsigned long subdirs;
|
|
/* children rbtree starts here and goes through kn->rb */
|
|
struct rb_root children;
|
|
|
|
/*
|
|
* The kernfs hierarchy this directory belongs to. This fits
|
|
* better directly in kernfs_node but is here to save space.
|
|
*/
|
|
struct kernfs_root *root;
|
|
};
|
|
|
|
struct kernfs_elem_symlink {
|
|
struct kernfs_node *target_kn;
|
|
};
|
|
|
|
struct kernfs_elem_attr {
|
|
const struct kernfs_ops *ops;
|
|
struct kernfs_open_node *open;
|
|
loff_t size;
|
|
struct kernfs_node *notify_next; /* for kernfs_notify() */
|
|
};
|
|
|
|
/* represent a kernfs node */
|
|
union kernfs_node_id {
|
|
struct {
|
|
/*
|
|
* blktrace will export this struct as a simplified 'struct
|
|
* fid' (which is a big data struction), so userspace can use
|
|
* it to find kernfs node. The layout must match the first two
|
|
* fields of 'struct fid' exactly.
|
|
*/
|
|
u32 ino;
|
|
u32 generation;
|
|
};
|
|
u64 id;
|
|
};
|
|
|
|
/*
|
|
* kernfs_node - the building block of kernfs hierarchy. Each and every
|
|
* kernfs node is represented by single kernfs_node. Most fields are
|
|
* private to kernfs and shouldn't be accessed directly by kernfs users.
|
|
*
|
|
* As long as s_count reference is held, the kernfs_node itself is
|
|
* accessible. Dereferencing elem or any other outer entity requires
|
|
* active reference.
|
|
*/
|
|
struct kernfs_node {
|
|
atomic_t count;
|
|
atomic_t active;
|
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
|
struct lockdep_map dep_map;
|
|
#endif
|
|
/*
|
|
* Use kernfs_get_parent() and kernfs_name/path() instead of
|
|
* accessing the following two fields directly. If the node is
|
|
* never moved to a different parent, it is safe to access the
|
|
* parent directly.
|
|
*/
|
|
struct kernfs_node *parent;
|
|
const char *name;
|
|
|
|
struct rb_node rb;
|
|
|
|
const void *ns; /* namespace tag */
|
|
unsigned int hash; /* ns + name hash */
|
|
union {
|
|
struct kernfs_elem_dir dir;
|
|
struct kernfs_elem_symlink symlink;
|
|
struct kernfs_elem_attr attr;
|
|
};
|
|
|
|
void *priv;
|
|
|
|
union kernfs_node_id id;
|
|
unsigned short flags;
|
|
umode_t mode;
|
|
struct kernfs_iattrs *iattr;
|
|
};
|
|
|
|
/*
|
|
* kernfs_syscall_ops may be specified on kernfs_create_root() to support
|
|
* 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. An active reference is held for each
|
|
* kernfs_node parameter.
|
|
*/
|
|
struct kernfs_syscall_ops {
|
|
int (*remount_fs)(struct kernfs_root *root, int *flags, char *data);
|
|
int (*show_options)(struct seq_file *sf, struct kernfs_root *root);
|
|
|
|
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);
|
|
int (*show_path)(struct seq_file *sf, struct kernfs_node *kn,
|
|
struct kernfs_root *root);
|
|
};
|
|
|
|
struct kernfs_root {
|
|
/* published fields */
|
|
struct kernfs_node *kn;
|
|
unsigned int flags; /* KERNFS_ROOT_* flags */
|
|
|
|
/* private fields, do not use outside kernfs proper */
|
|
struct idr ino_idr;
|
|
u32 last_ino;
|
|
u32 next_generation;
|
|
struct kernfs_syscall_ops *syscall_ops;
|
|
|
|
/* list of kernfs_super_info of this root, protected by kernfs_mutex */
|
|
struct list_head supers;
|
|
|
|
wait_queue_head_t deactivate_waitq;
|
|
};
|
|
|
|
struct kernfs_open_file {
|
|
/* published fields */
|
|
struct kernfs_node *kn;
|
|
struct file *file;
|
|
struct seq_file *seq_file;
|
|
void *priv;
|
|
|
|
/* private fields, do not use outside kernfs proper */
|
|
struct mutex mutex;
|
|
struct mutex prealloc_mutex;
|
|
int event;
|
|
struct list_head list;
|
|
char *prealloc_buf;
|
|
|
|
size_t atomic_write_len;
|
|
bool mmapped:1;
|
|
bool released:1;
|
|
const struct vm_operations_struct *vm_ops;
|
|
};
|
|
|
|
struct kernfs_ops {
|
|
/*
|
|
* Optional open/release methods. Both are called with
|
|
* @of->seq_file populated.
|
|
*/
|
|
int (*open)(struct kernfs_open_file *of);
|
|
void (*release)(struct kernfs_open_file *of);
|
|
|
|
/*
|
|
* Read is handled by either seq_file or raw_read().
|
|
*
|
|
* 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
|
|
* associated kernfs_open_file.
|
|
*
|
|
* 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);
|
|
|
|
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);
|
|
|
|
ssize_t (*read)(struct kernfs_open_file *of, char *buf, size_t bytes,
|
|
loff_t off);
|
|
|
|
/*
|
|
* write() is bounced through kernel buffer. If atomic_write_len
|
|
* is not set, a write larger than PAGE_SIZE results in partial
|
|
* operations of PAGE_SIZE chunks. If atomic_write_len is set,
|
|
* writes upto the specified size are executed atomically but
|
|
* larger ones are rejected with -E2BIG.
|
|
*/
|
|
size_t atomic_write_len;
|
|
/*
|
|
* "prealloc" causes a buffer to be allocated at open for
|
|
* all read/write requests. As ->seq_show uses seq_read()
|
|
* which does its own allocation, it is incompatible with
|
|
* ->prealloc. Provide ->read and ->write with ->prealloc.
|
|
*/
|
|
bool prealloc;
|
|
ssize_t (*write)(struct kernfs_open_file *of, char *buf, size_t bytes,
|
|
loff_t off);
|
|
|
|
int (*mmap)(struct kernfs_open_file *of, struct vm_area_struct *vma);
|
|
|
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
|
struct lock_class_key lockdep_key;
|
|
#endif
|
|
};
|
|
|
|
#ifdef CONFIG_KERNFS
|
|
|
|
static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn)
|
|
{
|
|
return kn->flags & KERNFS_TYPE_MASK;
|
|
}
|
|
|
|
/**
|
|
* kernfs_enable_ns - enable namespace under a directory
|
|
* @kn: directory of interest, should be empty
|
|
*
|
|
* 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
|
|
* only the ones which match the super_block's tag will be visible.
|
|
*/
|
|
static inline void kernfs_enable_ns(struct kernfs_node *kn)
|
|
{
|
|
WARN_ON_ONCE(kernfs_type(kn) != KERNFS_DIR);
|
|
WARN_ON_ONCE(!RB_EMPTY_ROOT(&kn->dir.children));
|
|
kn->flags |= KERNFS_NS;
|
|
}
|
|
|
|
/**
|
|
* kernfs_ns_enabled - test whether namespace is enabled
|
|
* @kn: the node to test
|
|
*
|
|
* Test whether namespace filtering is enabled for the children of @ns.
|
|
*/
|
|
static inline bool kernfs_ns_enabled(struct kernfs_node *kn)
|
|
{
|
|
return kn->flags & KERNFS_NS;
|
|
}
|
|
|
|
int kernfs_name(struct kernfs_node *kn, char *buf, size_t buflen);
|
|
int kernfs_path_from_node(struct kernfs_node *root_kn, struct kernfs_node *kn,
|
|
char *buf, size_t buflen);
|
|
void pr_cont_kernfs_name(struct kernfs_node *kn);
|
|
void pr_cont_kernfs_path(struct kernfs_node *kn);
|
|
struct kernfs_node *kernfs_get_parent(struct kernfs_node *kn);
|
|
struct kernfs_node *kernfs_find_and_get_ns(struct kernfs_node *parent,
|
|
const char *name, const void *ns);
|
|
struct kernfs_node *kernfs_walk_and_get_ns(struct kernfs_node *parent,
|
|
const char *path, const void *ns);
|
|
void kernfs_get(struct kernfs_node *kn);
|
|
void kernfs_put(struct kernfs_node *kn);
|
|
|
|
struct kernfs_node *kernfs_node_from_dentry(struct dentry *dentry);
|
|
struct kernfs_root *kernfs_root_from_sb(struct super_block *sb);
|
|
struct inode *kernfs_get_inode(struct super_block *sb, struct kernfs_node *kn);
|
|
|
|
struct dentry *kernfs_node_dentry(struct kernfs_node *kn,
|
|
struct super_block *sb);
|
|
struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops,
|
|
unsigned int flags, void *priv);
|
|
void kernfs_destroy_root(struct kernfs_root *root);
|
|
|
|
struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent,
|
|
const char *name, umode_t mode,
|
|
kuid_t uid, kgid_t gid,
|
|
void *priv, const void *ns);
|
|
struct kernfs_node *kernfs_create_empty_dir(struct kernfs_node *parent,
|
|
const char *name);
|
|
struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent,
|
|
const char *name, umode_t mode,
|
|
kuid_t uid, kgid_t gid,
|
|
loff_t size,
|
|
const struct kernfs_ops *ops,
|
|
void *priv, const void *ns,
|
|
struct lock_class_key *key);
|
|
struct kernfs_node *kernfs_create_link(struct kernfs_node *parent,
|
|
const char *name,
|
|
struct kernfs_node *target);
|
|
void kernfs_activate(struct kernfs_node *kn);
|
|
void kernfs_remove(struct kernfs_node *kn);
|
|
void kernfs_break_active_protection(struct kernfs_node *kn);
|
|
void kernfs_unbreak_active_protection(struct kernfs_node *kn);
|
|
bool kernfs_remove_self(struct kernfs_node *kn);
|
|
int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name,
|
|
const void *ns);
|
|
int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
|
|
const char *new_name, const void *new_ns);
|
|
int kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr);
|
|
void kernfs_notify(struct kernfs_node *kn);
|
|
|
|
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, unsigned long magic,
|
|
bool *new_sb_created, const void *ns);
|
|
void kernfs_kill_sb(struct super_block *sb);
|
|
struct super_block *kernfs_pin_sb(struct kernfs_root *root, const void *ns);
|
|
|
|
void kernfs_init(void);
|
|
|
|
struct kernfs_node *kernfs_get_node_by_id(struct kernfs_root *root,
|
|
const union kernfs_node_id *id);
|
|
#else /* CONFIG_KERNFS */
|
|
|
|
static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn)
|
|
{ return 0; } /* whatever */
|
|
|
|
static inline void kernfs_enable_ns(struct kernfs_node *kn) { }
|
|
|
|
static inline bool kernfs_ns_enabled(struct kernfs_node *kn)
|
|
{ return false; }
|
|
|
|
static inline int kernfs_name(struct kernfs_node *kn, char *buf, size_t buflen)
|
|
{ return -ENOSYS; }
|
|
|
|
static inline int kernfs_path_from_node(struct kernfs_node *root_kn,
|
|
struct kernfs_node *kn,
|
|
char *buf, size_t buflen)
|
|
{ return -ENOSYS; }
|
|
|
|
static inline void pr_cont_kernfs_name(struct kernfs_node *kn) { }
|
|
static inline void pr_cont_kernfs_path(struct kernfs_node *kn) { }
|
|
|
|
static inline struct kernfs_node *kernfs_get_parent(struct kernfs_node *kn)
|
|
{ return NULL; }
|
|
|
|
static inline struct kernfs_node *
|
|
kernfs_find_and_get_ns(struct kernfs_node *parent, const char *name,
|
|
const void *ns)
|
|
{ return NULL; }
|
|
static inline struct kernfs_node *
|
|
kernfs_walk_and_get_ns(struct kernfs_node *parent, const char *path,
|
|
const void *ns)
|
|
{ return NULL; }
|
|
|
|
static inline void kernfs_get(struct kernfs_node *kn) { }
|
|
static inline void kernfs_put(struct kernfs_node *kn) { }
|
|
|
|
static inline struct kernfs_node *kernfs_node_from_dentry(struct dentry *dentry)
|
|
{ return NULL; }
|
|
|
|
static inline struct kernfs_root *kernfs_root_from_sb(struct super_block *sb)
|
|
{ return NULL; }
|
|
|
|
static inline struct inode *
|
|
kernfs_get_inode(struct super_block *sb, struct kernfs_node *kn)
|
|
{ return NULL; }
|
|
|
|
static inline struct kernfs_root *
|
|
kernfs_create_root(struct kernfs_syscall_ops *scops, unsigned int flags,
|
|
void *priv)
|
|
{ return ERR_PTR(-ENOSYS); }
|
|
|
|
static inline void kernfs_destroy_root(struct kernfs_root *root) { }
|
|
|
|
static inline struct kernfs_node *
|
|
kernfs_create_dir_ns(struct kernfs_node *parent, const char *name,
|
|
umode_t mode, kuid_t uid, kgid_t gid,
|
|
void *priv, const void *ns)
|
|
{ return ERR_PTR(-ENOSYS); }
|
|
|
|
static inline struct kernfs_node *
|
|
__kernfs_create_file(struct kernfs_node *parent, const char *name,
|
|
umode_t mode, kuid_t uid, kgid_t gid,
|
|
loff_t size, const struct kernfs_ops *ops,
|
|
void *priv, const void *ns, struct lock_class_key *key)
|
|
{ return ERR_PTR(-ENOSYS); }
|
|
|
|
static inline struct kernfs_node *
|
|
kernfs_create_link(struct kernfs_node *parent, const char *name,
|
|
struct kernfs_node *target)
|
|
{ return ERR_PTR(-ENOSYS); }
|
|
|
|
static inline void kernfs_activate(struct kernfs_node *kn) { }
|
|
|
|
static inline void kernfs_remove(struct kernfs_node *kn) { }
|
|
|
|
static inline bool kernfs_remove_self(struct kernfs_node *kn)
|
|
{ return false; }
|
|
|
|
static inline int kernfs_remove_by_name_ns(struct kernfs_node *kn,
|
|
const char *name, const void *ns)
|
|
{ return -ENOSYS; }
|
|
|
|
static inline int kernfs_rename_ns(struct kernfs_node *kn,
|
|
struct kernfs_node *new_parent,
|
|
const char *new_name, const void *new_ns)
|
|
{ return -ENOSYS; }
|
|
|
|
static inline int kernfs_setattr(struct kernfs_node *kn,
|
|
const struct iattr *iattr)
|
|
{ return -ENOSYS; }
|
|
|
|
static inline void kernfs_notify(struct kernfs_node *kn) { }
|
|
|
|
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, unsigned long magic,
|
|
bool *new_sb_created, const void *ns)
|
|
{ return ERR_PTR(-ENOSYS); }
|
|
|
|
static inline void kernfs_kill_sb(struct super_block *sb) { }
|
|
|
|
static inline void kernfs_init(void) { }
|
|
|
|
#endif /* CONFIG_KERNFS */
|
|
|
|
/**
|
|
* kernfs_path - build full path of a given node
|
|
* @kn: kernfs_node of interest
|
|
* @buf: buffer to copy @kn's name into
|
|
* @buflen: size of @buf
|
|
*
|
|
* Builds and returns the full path of @kn in @buf of @buflen bytes. The
|
|
* path is built from the end of @buf so the returned pointer usually
|
|
* doesn't match @buf. If @buf isn't long enough, @buf is nul terminated
|
|
* and %NULL is returned.
|
|
*/
|
|
static inline int kernfs_path(struct kernfs_node *kn, char *buf, size_t buflen)
|
|
{
|
|
return kernfs_path_from_node(kn, NULL, buf, buflen);
|
|
}
|
|
|
|
static inline struct kernfs_node *
|
|
kernfs_find_and_get(struct kernfs_node *kn, const char *name)
|
|
{
|
|
return kernfs_find_and_get_ns(kn, name, NULL);
|
|
}
|
|
|
|
static inline struct kernfs_node *
|
|
kernfs_walk_and_get(struct kernfs_node *kn, const char *path)
|
|
{
|
|
return kernfs_walk_and_get_ns(kn, path, NULL);
|
|
}
|
|
|
|
static inline struct kernfs_node *
|
|
kernfs_create_dir(struct kernfs_node *parent, const char *name, umode_t mode,
|
|
void *priv)
|
|
{
|
|
return kernfs_create_dir_ns(parent, name, mode,
|
|
GLOBAL_ROOT_UID, GLOBAL_ROOT_GID,
|
|
priv, NULL);
|
|
}
|
|
|
|
static inline struct kernfs_node *
|
|
kernfs_create_file_ns(struct kernfs_node *parent, const char *name,
|
|
umode_t mode, kuid_t uid, kgid_t gid,
|
|
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
|
|
return __kernfs_create_file(parent, name, mode, uid, gid,
|
|
size, ops, priv, ns, key);
|
|
}
|
|
|
|
static inline 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)
|
|
{
|
|
return kernfs_create_file_ns(parent, name, mode,
|
|
GLOBAL_ROOT_UID, GLOBAL_ROOT_GID,
|
|
size, ops, priv, NULL);
|
|
}
|
|
|
|
static inline int kernfs_remove_by_name(struct kernfs_node *parent,
|
|
const char *name)
|
|
{
|
|
return kernfs_remove_by_name_ns(parent, name, NULL);
|
|
}
|
|
|
|
static inline int kernfs_rename(struct kernfs_node *kn,
|
|
struct kernfs_node *new_parent,
|
|
const char *new_name)
|
|
{
|
|
return kernfs_rename_ns(kn, new_parent, new_name, NULL);
|
|
}
|
|
|
|
static inline struct dentry *
|
|
kernfs_mount(struct file_system_type *fs_type, int flags,
|
|
struct kernfs_root *root, unsigned long magic,
|
|
bool *new_sb_created)
|
|
{
|
|
return kernfs_mount_ns(fs_type, flags, root,
|
|
magic, new_sb_created, NULL);
|
|
}
|
|
|
|
#endif /* __LINUX_KERNFS_H */
|