summaryrefslogtreecommitdiff
path: root/include/linux/kernfs.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/kernfs.h')
-rw-r--r--include/linux/kernfs.h53
1 files changed, 32 insertions, 21 deletions
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index b5a5f32fdfd1..351a5101c862 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -23,6 +23,7 @@
struct file;
struct dentry;
struct iattr;
+struct ns_common;
struct seq_file;
struct vm_area_struct;
struct vm_operations_struct;
@@ -75,20 +76,25 @@ struct kernfs_iattrs;
* kernfs_open_file.
*
* kernfs_open_files are chained at kernfs_open_node->files, which is
- * protected by kernfs_global_locks.open_file_mutex[i].
+ * protected by kernfs_global_locks.node_mutex[i].
*
* To reduce possible contention in sysfs access, arising due to single
- * locks, use an array of locks (e.g. open_file_mutex) and use kernfs_node
+ * locks, use an array of locks (e.g. node_mutex) and use kernfs_node
* object address as hash keys to get the index of these locks.
*
* Hashed mutexes are safe to use here because operations using these don't
* rely on global exclusion.
*
+ * The hashed mutex array protects per-node data: the kernfs_open_node for
+ * open file management, and kernfs_node xattr operations (necessary because
+ * multiple superblocks with different namespaces can share the same
+ * kernfs_node, making per-inode locking insufficient).
+ *
* In future we intend to replace other global locks with hashed ones as well.
* kernfs_global_locks acts as a holder for all such hash tables.
*/
struct kernfs_global_locks {
- struct mutex open_file_mutex[NR_KERNFS_LOCKS];
+ struct mutex node_mutex[NR_KERNFS_LOCKS];
};
enum kernfs_node_type {
@@ -99,8 +105,6 @@ enum kernfs_node_type {
#define KERNFS_TYPE_MASK 0x000f
#define KERNFS_FLAG_MASK ~KERNFS_TYPE_MASK
-#define KERNFS_MAX_USER_XATTRS 128
-#define KERNFS_USER_XATTR_SIZE_LIMIT (128 << 10)
enum kernfs_node_flag {
KERNFS_ACTIVATED = 0x0010,
@@ -209,7 +213,7 @@ struct kernfs_node {
struct rb_node rb;
- const void *ns; /* namespace tag */
+ const struct ns_common *ns; /* namespace tag */
unsigned int hash; /* ns + name hash */
unsigned short flags;
umode_t mode;
@@ -331,7 +335,7 @@ struct kernfs_ops {
*/
struct kernfs_fs_context {
struct kernfs_root *root; /* Root of the hierarchy being mounted */
- void *ns_tag; /* Namespace tag of the mount (or NULL) */
+ struct ns_common *ns_tag; /* Namespace tag of the mount (or NULL) */
unsigned long magic; /* File system specific magic number */
/* The following are set/used by kernfs_mount() */
@@ -406,9 +410,11 @@ 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);
+ const char *name,
+ const struct ns_common *ns);
struct kernfs_node *kernfs_walk_and_get_ns(struct kernfs_node *parent,
- const char *path, const void *ns);
+ const char *path,
+ const struct ns_common *ns);
void kernfs_get(struct kernfs_node *kn);
void kernfs_put(struct kernfs_node *kn);
@@ -426,7 +432,8 @@ unsigned int kernfs_root_flags(struct kernfs_node *kn);
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);
+ void *priv,
+ const struct ns_common *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,
@@ -434,7 +441,8 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent,
kuid_t uid, kgid_t gid,
loff_t size,
const struct kernfs_ops *ops,
- void *priv, const void *ns,
+ void *priv,
+ const struct ns_common *ns,
struct lock_class_key *key);
struct kernfs_node *kernfs_create_link(struct kernfs_node *parent,
const char *name,
@@ -446,9 +454,9 @@ 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);
+ const struct ns_common *ns);
int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
- const char *new_name, const void *new_ns);
+ const char *new_name, const struct ns_common *new_ns);
int kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr);
__poll_t kernfs_generic_poll(struct kernfs_open_file *of,
struct poll_table_struct *pt);
@@ -459,7 +467,7 @@ int kernfs_xattr_get(struct kernfs_node *kn, const char *name,
int kernfs_xattr_set(struct kernfs_node *kn, const char *name,
const void *value, size_t size, int flags);
-const void *kernfs_super_ns(struct super_block *sb);
+const struct ns_common *kernfs_super_ns(struct super_block *sb);
int kernfs_get_tree(struct fs_context *fc);
void kernfs_free_fs_context(struct fs_context *fc);
void kernfs_kill_sb(struct super_block *sb);
@@ -494,11 +502,11 @@ static inline struct kernfs_node *kernfs_get_parent(struct kernfs_node *kn)
static inline struct kernfs_node *
kernfs_find_and_get_ns(struct kernfs_node *parent, const char *name,
- const void *ns)
+ const struct ns_common *ns)
{ return NULL; }
static inline struct kernfs_node *
kernfs_walk_and_get_ns(struct kernfs_node *parent, const char *path,
- const void *ns)
+ const struct ns_common *ns)
{ return NULL; }
static inline void kernfs_get(struct kernfs_node *kn) { }
@@ -526,14 +534,15 @@ static inline unsigned int kernfs_root_flags(struct kernfs_node *kn)
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)
+ void *priv, const struct ns_common *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)
+ void *priv, const struct ns_common *ns,
+ struct lock_class_key *key)
{ return ERR_PTR(-ENOSYS); }
static inline struct kernfs_node *
@@ -549,12 +558,14 @@ 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)
+ const char *name,
+ const struct ns_common *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)
+ const char *new_name,
+ const struct ns_common *new_ns)
{ return -ENOSYS; }
static inline int kernfs_setattr(struct kernfs_node *kn,
@@ -575,7 +586,7 @@ static inline int kernfs_xattr_set(struct kernfs_node *kn, const char *name,
const void *value, size_t size, int flags)
{ return -ENOSYS; }
-static inline const void *kernfs_super_ns(struct super_block *sb)
+static inline const struct ns_common *kernfs_super_ns(struct super_block *sb)
{ return NULL; }
static inline int kernfs_get_tree(struct fs_context *fc)