at v3.14 11 kB view raw
1/* 2 * kernfs.h - pseudo filesystem decoupled from vfs locking 3 * 4 * This file is released under the GPLv2. 5 */ 6 7#ifndef __LINUX_KERNFS_H 8#define __LINUX_KERNFS_H 9 10#include <linux/kernel.h> 11#include <linux/err.h> 12#include <linux/list.h> 13#include <linux/mutex.h> 14#include <linux/idr.h> 15#include <linux/lockdep.h> 16#include <linux/rbtree.h> 17#include <linux/atomic.h> 18#include <linux/completion.h> 19 20struct file; 21struct dentry; 22struct iattr; 23struct seq_file; 24struct vm_area_struct; 25struct super_block; 26struct file_system_type; 27 28struct kernfs_open_node; 29struct kernfs_iattrs; 30 31enum kernfs_node_type { 32 KERNFS_DIR = 0x0001, 33 KERNFS_FILE = 0x0002, 34 KERNFS_LINK = 0x0004, 35}; 36 37#define KERNFS_TYPE_MASK 0x000f 38#define KERNFS_ACTIVE_REF KERNFS_FILE 39#define KERNFS_FLAG_MASK ~KERNFS_TYPE_MASK 40 41enum kernfs_node_flag { 42 KERNFS_REMOVED = 0x0010, 43 KERNFS_NS = 0x0020, 44 KERNFS_HAS_SEQ_SHOW = 0x0040, 45 KERNFS_HAS_MMAP = 0x0080, 46 KERNFS_LOCKDEP = 0x0100, 47 KERNFS_STATIC_NAME = 0x0200, 48}; 49 50/* type-specific structures for kernfs_node union members */ 51struct kernfs_elem_dir { 52 unsigned long subdirs; 53 /* children rbtree starts here and goes through kn->rb */ 54 struct rb_root children; 55 56 /* 57 * The kernfs hierarchy this directory belongs to. This fits 58 * better directly in kernfs_node but is here to save space. 59 */ 60 struct kernfs_root *root; 61}; 62 63struct kernfs_elem_symlink { 64 struct kernfs_node *target_kn; 65}; 66 67struct kernfs_elem_attr { 68 const struct kernfs_ops *ops; 69 struct kernfs_open_node *open; 70 loff_t size; 71}; 72 73/* 74 * kernfs_node - the building block of kernfs hierarchy. Each and every 75 * kernfs node is represented by single kernfs_node. Most fields are 76 * private to kernfs and shouldn't be accessed directly by kernfs users. 77 * 78 * As long as s_count reference is held, the kernfs_node itself is 79 * accessible. Dereferencing elem or any other outer entity requires 80 * active reference. 81 */ 82struct kernfs_node { 83 atomic_t count; 84 atomic_t active; 85#ifdef CONFIG_DEBUG_LOCK_ALLOC 86 struct lockdep_map dep_map; 87#endif 88 /* the following two fields are published */ 89 struct kernfs_node *parent; 90 const char *name; 91 92 struct rb_node rb; 93 94 union { 95 struct completion *completion; 96 struct kernfs_node *removed_list; 97 } u; 98 99 const void *ns; /* namespace tag */ 100 unsigned int hash; /* ns + name hash */ 101 union { 102 struct kernfs_elem_dir dir; 103 struct kernfs_elem_symlink symlink; 104 struct kernfs_elem_attr attr; 105 }; 106 107 void *priv; 108 109 unsigned short flags; 110 umode_t mode; 111 unsigned int ino; 112 struct kernfs_iattrs *iattr; 113}; 114 115/* 116 * kernfs_dir_ops may be specified on kernfs_create_root() to support 117 * directory manipulation syscalls. These optional callbacks are invoked 118 * on the matching syscalls and can perform any kernfs operations which 119 * don't necessarily have to be the exact operation requested. 120 */ 121struct kernfs_dir_ops { 122 int (*mkdir)(struct kernfs_node *parent, const char *name, 123 umode_t mode); 124 int (*rmdir)(struct kernfs_node *kn); 125 int (*rename)(struct kernfs_node *kn, struct kernfs_node *new_parent, 126 const char *new_name); 127}; 128 129struct kernfs_root { 130 /* published fields */ 131 struct kernfs_node *kn; 132 133 /* private fields, do not use outside kernfs proper */ 134 struct ida ino_ida; 135 struct kernfs_dir_ops *dir_ops; 136}; 137 138struct kernfs_open_file { 139 /* published fields */ 140 struct kernfs_node *kn; 141 struct file *file; 142 143 /* private fields, do not use outside kernfs proper */ 144 struct mutex mutex; 145 int event; 146 struct list_head list; 147 148 bool mmapped; 149 const struct vm_operations_struct *vm_ops; 150}; 151 152struct kernfs_ops { 153 /* 154 * Read is handled by either seq_file or raw_read(). 155 * 156 * If seq_show() is present, seq_file path is active. Other seq 157 * operations are optional and if not implemented, the behavior is 158 * equivalent to single_open(). @sf->private points to the 159 * associated kernfs_open_file. 160 * 161 * read() is bounced through kernel buffer and a read larger than 162 * PAGE_SIZE results in partial operation of PAGE_SIZE. 163 */ 164 int (*seq_show)(struct seq_file *sf, void *v); 165 166 void *(*seq_start)(struct seq_file *sf, loff_t *ppos); 167 void *(*seq_next)(struct seq_file *sf, void *v, loff_t *ppos); 168 void (*seq_stop)(struct seq_file *sf, void *v); 169 170 ssize_t (*read)(struct kernfs_open_file *of, char *buf, size_t bytes, 171 loff_t off); 172 173 /* 174 * write() is bounced through kernel buffer and a write larger than 175 * PAGE_SIZE results in partial operation of PAGE_SIZE. 176 */ 177 ssize_t (*write)(struct kernfs_open_file *of, char *buf, size_t bytes, 178 loff_t off); 179 180 int (*mmap)(struct kernfs_open_file *of, struct vm_area_struct *vma); 181 182#ifdef CONFIG_DEBUG_LOCK_ALLOC 183 struct lock_class_key lockdep_key; 184#endif 185}; 186 187#ifdef CONFIG_SYSFS 188 189static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn) 190{ 191 return kn->flags & KERNFS_TYPE_MASK; 192} 193 194/** 195 * kernfs_enable_ns - enable namespace under a directory 196 * @kn: directory of interest, should be empty 197 * 198 * This is to be called right after @kn is created to enable namespace 199 * under it. All children of @kn must have non-NULL namespace tags and 200 * only the ones which match the super_block's tag will be visible. 201 */ 202static inline void kernfs_enable_ns(struct kernfs_node *kn) 203{ 204 WARN_ON_ONCE(kernfs_type(kn) != KERNFS_DIR); 205 WARN_ON_ONCE(!RB_EMPTY_ROOT(&kn->dir.children)); 206 kn->flags |= KERNFS_NS; 207} 208 209/** 210 * kernfs_ns_enabled - test whether namespace is enabled 211 * @kn: the node to test 212 * 213 * Test whether namespace filtering is enabled for the children of @ns. 214 */ 215static inline bool kernfs_ns_enabled(struct kernfs_node *kn) 216{ 217 return kn->flags & KERNFS_NS; 218} 219 220struct kernfs_node *kernfs_find_and_get_ns(struct kernfs_node *parent, 221 const char *name, const void *ns); 222void kernfs_get(struct kernfs_node *kn); 223void kernfs_put(struct kernfs_node *kn); 224 225struct kernfs_root *kernfs_create_root(struct kernfs_dir_ops *kdops, 226 void *priv); 227void kernfs_destroy_root(struct kernfs_root *root); 228 229struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, 230 const char *name, umode_t mode, 231 void *priv, const void *ns); 232struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, 233 const char *name, 234 umode_t mode, loff_t size, 235 const struct kernfs_ops *ops, 236 void *priv, const void *ns, 237 bool name_is_static, 238 struct lock_class_key *key); 239struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, 240 const char *name, 241 struct kernfs_node *target); 242void kernfs_remove(struct kernfs_node *kn); 243int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name, 244 const void *ns); 245int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, 246 const char *new_name, const void *new_ns); 247int kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr); 248void kernfs_notify(struct kernfs_node *kn); 249 250const void *kernfs_super_ns(struct super_block *sb); 251struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, 252 struct kernfs_root *root, bool *new_sb_created, 253 const void *ns); 254void kernfs_kill_sb(struct super_block *sb); 255 256void kernfs_init(void); 257 258#else /* CONFIG_SYSFS */ 259 260static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn) 261{ return 0; } /* whatever */ 262 263static inline void kernfs_enable_ns(struct kernfs_node *kn) { } 264 265static inline bool kernfs_ns_enabled(struct kernfs_node *kn) 266{ return false; } 267 268static inline struct kernfs_node * 269kernfs_find_and_get_ns(struct kernfs_node *parent, const char *name, 270 const void *ns) 271{ return NULL; } 272 273static inline void kernfs_get(struct kernfs_node *kn) { } 274static inline void kernfs_put(struct kernfs_node *kn) { } 275 276static inline struct kernfs_root * 277kernfs_create_root(struct kernfs_dir_ops *kdops, void *priv) 278{ return ERR_PTR(-ENOSYS); } 279 280static inline void kernfs_destroy_root(struct kernfs_root *root) { } 281 282static inline struct kernfs_node * 283kernfs_create_dir_ns(struct kernfs_node *parent, const char *name, 284 umode_t mode, void *priv, const void *ns) 285{ return ERR_PTR(-ENOSYS); } 286 287static inline struct kernfs_node * 288__kernfs_create_file(struct kernfs_node *parent, const char *name, 289 umode_t mode, loff_t size, const struct kernfs_ops *ops, 290 void *priv, const void *ns, bool name_is_static, 291 struct lock_class_key *key) 292{ return ERR_PTR(-ENOSYS); } 293 294static inline struct kernfs_node * 295kernfs_create_link(struct kernfs_node *parent, const char *name, 296 struct kernfs_node *target) 297{ return ERR_PTR(-ENOSYS); } 298 299static inline void kernfs_remove(struct kernfs_node *kn) { } 300 301static inline int kernfs_remove_by_name_ns(struct kernfs_node *kn, 302 const char *name, const void *ns) 303{ return -ENOSYS; } 304 305static inline int kernfs_rename_ns(struct kernfs_node *kn, 306 struct kernfs_node *new_parent, 307 const char *new_name, const void *new_ns) 308{ return -ENOSYS; } 309 310static inline int kernfs_setattr(struct kernfs_node *kn, 311 const struct iattr *iattr) 312{ return -ENOSYS; } 313 314static inline void kernfs_notify(struct kernfs_node *kn) { } 315 316static inline const void *kernfs_super_ns(struct super_block *sb) 317{ return NULL; } 318 319static inline struct dentry * 320kernfs_mount_ns(struct file_system_type *fs_type, int flags, 321 struct kernfs_root *root, bool *new_sb_created, const void *ns) 322{ return ERR_PTR(-ENOSYS); } 323 324static inline void kernfs_kill_sb(struct super_block *sb) { } 325 326static inline void kernfs_init(void) { } 327 328#endif /* CONFIG_SYSFS */ 329 330static inline struct kernfs_node * 331kernfs_find_and_get(struct kernfs_node *kn, const char *name) 332{ 333 return kernfs_find_and_get_ns(kn, name, NULL); 334} 335 336static inline struct kernfs_node * 337kernfs_create_dir(struct kernfs_node *parent, const char *name, umode_t mode, 338 void *priv) 339{ 340 return kernfs_create_dir_ns(parent, name, mode, priv, NULL); 341} 342 343static inline struct kernfs_node * 344kernfs_create_file_ns(struct kernfs_node *parent, const char *name, 345 umode_t mode, loff_t size, const struct kernfs_ops *ops, 346 void *priv, const void *ns) 347{ 348 struct lock_class_key *key = NULL; 349 350#ifdef CONFIG_DEBUG_LOCK_ALLOC 351 key = (struct lock_class_key *)&ops->lockdep_key; 352#endif 353 return __kernfs_create_file(parent, name, mode, size, ops, priv, ns, 354 false, key); 355} 356 357static inline struct kernfs_node * 358kernfs_create_file(struct kernfs_node *parent, const char *name, umode_t mode, 359 loff_t size, const struct kernfs_ops *ops, void *priv) 360{ 361 return kernfs_create_file_ns(parent, name, mode, size, ops, priv, NULL); 362} 363 364static inline int kernfs_remove_by_name(struct kernfs_node *parent, 365 const char *name) 366{ 367 return kernfs_remove_by_name_ns(parent, name, NULL); 368} 369 370static inline struct dentry * 371kernfs_mount(struct file_system_type *fs_type, int flags, 372 struct kernfs_root *root, bool *new_sb_created) 373{ 374 return kernfs_mount_ns(fs_type, flags, root, new_sb_created, NULL); 375} 376 377#endif /* __LINUX_KERNFS_H */