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 20 struct file; 21 struct iattr; 22 struct seq_file; 23 struct vm_area_struct; 24 struct super_block; 25 struct file_system_type; 26 27 struct sysfs_open_dirent; 28 struct sysfs_inode_attrs; 29 30 enum kernfs_node_type { 31 SYSFS_DIR = 0x0001, 32 SYSFS_KOBJ_ATTR = 0x0002, 33 SYSFS_KOBJ_LINK = 0x0004, 34 }; 35 36 #define SYSFS_TYPE_MASK 0x000f 37 #define SYSFS_COPY_NAME (SYSFS_DIR | SYSFS_KOBJ_LINK) 38 #define SYSFS_ACTIVE_REF SYSFS_KOBJ_ATTR 39 #define SYSFS_FLAG_MASK ~SYSFS_TYPE_MASK 40 41 enum kernfs_node_flag { 42 SYSFS_FLAG_REMOVED = 0x0010, 43 SYSFS_FLAG_NS = 0x0020, 44 SYSFS_FLAG_HAS_SEQ_SHOW = 0x0040, 45 SYSFS_FLAG_HAS_MMAP = 0x0080, 46 SYSFS_FLAG_LOCKDEP = 0x0100, 47 }; 48 49 /* type-specific structures for sysfs_dirent->s_* union members */ 50 struct sysfs_elem_dir { 51 unsigned long subdirs; 52 /* children rbtree starts here and goes through sd->s_rb */ 53 struct rb_root children; 54 55 /* 56 * The kernfs hierarchy this directory belongs to. This fits 57 * better directly in sysfs_dirent but is here to save space. 58 */ 59 struct kernfs_root *root; 60 }; 61 62 struct sysfs_elem_symlink { 63 struct sysfs_dirent *target_sd; 64 }; 65 66 struct sysfs_elem_attr { 67 const struct kernfs_ops *ops; 68 struct sysfs_open_dirent *open; 69 loff_t size; 70 }; 71 72 /* 73 * sysfs_dirent - the building block of sysfs hierarchy. Each and every 74 * sysfs node is represented by single sysfs_dirent. Most fields are 75 * private to kernfs and shouldn't be accessed directly by kernfs users. 76 * 77 * As long as s_count reference is held, the sysfs_dirent itself is 78 * accessible. Dereferencing s_elem or any other outer entity 79 * requires s_active reference. 80 */ 81 struct sysfs_dirent { 82 atomic_t s_count; 83 atomic_t s_active; 84 #ifdef CONFIG_DEBUG_LOCK_ALLOC 85 struct lockdep_map dep_map; 86 #endif 87 /* the following two fields are published */ 88 struct sysfs_dirent *s_parent; 89 const char *s_name; 90 91 struct rb_node s_rb; 92 93 union { 94 struct completion *completion; 95 struct sysfs_dirent *removed_list; 96 } u; 97 98 const void *s_ns; /* namespace tag */ 99 unsigned int s_hash; /* ns + name hash */ 100 union { 101 struct sysfs_elem_dir s_dir; 102 struct sysfs_elem_symlink s_symlink; 103 struct sysfs_elem_attr s_attr; 104 }; 105 106 void *priv; 107 108 unsigned short s_flags; 109 umode_t s_mode; 110 unsigned int s_ino; 111 struct sysfs_inode_attrs *s_iattr; 112 }; 113 114 struct kernfs_root { 115 /* published fields */ 116 struct sysfs_dirent *sd; 117 118 /* private fields, do not use outside kernfs proper */ 119 struct ida ino_ida; 120 }; 121 122 struct sysfs_open_file { 123 /* published fields */ 124 struct sysfs_dirent *sd; 125 struct file *file; 126 127 /* private fields, do not use outside kernfs proper */ 128 struct mutex mutex; 129 int event; 130 struct list_head list; 131 132 bool mmapped; 133 const struct vm_operations_struct *vm_ops; 134 }; 135 136 struct kernfs_ops { 137 /* 138 * Read is handled by either seq_file or raw_read(). 139 * 140 * If seq_show() is present, seq_file path is active. Other seq 141 * operations are optional and if not implemented, the behavior is 142 * equivalent to single_open(). @sf->private points to the 143 * associated sysfs_open_file. 144 * 145 * read() is bounced through kernel buffer and a read larger than 146 * PAGE_SIZE results in partial operation of PAGE_SIZE. 147 */ 148 int (*seq_show)(struct seq_file *sf, void *v); 149 150 void *(*seq_start)(struct seq_file *sf, loff_t *ppos); 151 void *(*seq_next)(struct seq_file *sf, void *v, loff_t *ppos); 152 void (*seq_stop)(struct seq_file *sf, void *v); 153 154 ssize_t (*read)(struct sysfs_open_file *of, char *buf, size_t bytes, 155 loff_t off); 156 157 /* 158 * write() is bounced through kernel buffer and a write larger than 159 * PAGE_SIZE results in partial operation of PAGE_SIZE. 160 */ 161 ssize_t (*write)(struct sysfs_open_file *of, char *buf, size_t bytes, 162 loff_t off); 163 164 int (*mmap)(struct sysfs_open_file *of, struct vm_area_struct *vma); 165 166 #ifdef CONFIG_DEBUG_LOCK_ALLOC 167 struct lock_class_key lockdep_key; 168 #endif 169 }; 170 171 #ifdef CONFIG_SYSFS 172 173 static inline enum kernfs_node_type sysfs_type(struct sysfs_dirent *sd) 174 { 175 return sd->s_flags & SYSFS_TYPE_MASK; 176 } 177 178 /** 179 * kernfs_enable_ns - enable namespace under a directory 180 * @sd: directory of interest, should be empty 181 * 182 * This is to be called right after @sd is created to enable namespace 183 * under it. All children of @sd must have non-NULL namespace tags and 184 * only the ones which match the super_block's tag will be visible. 185 */ 186 static inline void kernfs_enable_ns(struct sysfs_dirent *sd) 187 { 188 WARN_ON_ONCE(sysfs_type(sd) != SYSFS_DIR); 189 WARN_ON_ONCE(!RB_EMPTY_ROOT(&sd->s_dir.children)); 190 sd->s_flags |= SYSFS_FLAG_NS; 191 } 192 193 /** 194 * kernfs_ns_enabled - test whether namespace is enabled 195 * @sd: the node to test 196 * 197 * Test whether namespace filtering is enabled for the children of @ns. 198 */ 199 static inline bool kernfs_ns_enabled(struct sysfs_dirent *sd) 200 { 201 return sd->s_flags & SYSFS_FLAG_NS; 202 } 203 204 struct sysfs_dirent *kernfs_find_and_get_ns(struct sysfs_dirent *parent, 205 const char *name, const void *ns); 206 void kernfs_get(struct sysfs_dirent *sd); 207 void kernfs_put(struct sysfs_dirent *sd); 208 209 struct kernfs_root *kernfs_create_root(void *priv); 210 void kernfs_destroy_root(struct kernfs_root *root); 211 212 struct sysfs_dirent *kernfs_create_dir_ns(struct sysfs_dirent *parent, 213 const char *name, void *priv, 214 const void *ns); 215 struct sysfs_dirent *kernfs_create_file_ns_key(struct sysfs_dirent *parent, 216 const char *name, 217 umode_t mode, loff_t size, 218 const struct kernfs_ops *ops, 219 void *priv, const void *ns, 220 struct lock_class_key *key); 221 struct sysfs_dirent *kernfs_create_link(struct sysfs_dirent *parent, 222 const char *name, 223 struct sysfs_dirent *target); 224 void kernfs_remove(struct sysfs_dirent *sd); 225 int kernfs_remove_by_name_ns(struct sysfs_dirent *parent, const char *name, 226 const void *ns); 227 int kernfs_rename_ns(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent, 228 const char *new_name, const void *new_ns); 229 int kernfs_setattr(struct sysfs_dirent *sd, const struct iattr *iattr); 230 void kernfs_notify(struct sysfs_dirent *sd); 231 232 const void *kernfs_super_ns(struct super_block *sb); 233 struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, 234 struct kernfs_root *root, const void *ns); 235 void kernfs_kill_sb(struct super_block *sb); 236 237 void kernfs_init(void); 238 239 #else /* CONFIG_SYSFS */ 240 241 static inline enum kernfs_node_type sysfs_type(struct sysfs_dirent *sd) 242 { return 0; } /* whatever */ 243 244 static inline void kernfs_enable_ns(struct sysfs_dirent *sd) { } 245 246 static inline bool kernfs_ns_enabled(struct sysfs_dirent *sd) 247 { return false; } 248 249 static inline struct sysfs_dirent * 250 kernfs_find_and_get_ns(struct sysfs_dirent *parent, const char *name, 251 const void *ns) 252 { return NULL; } 253 254 static inline void kernfs_get(struct sysfs_dirent *sd) { } 255 static inline void kernfs_put(struct sysfs_dirent *sd) { } 256 257 static inline struct kernfs_root *kernfs_create_root(void *priv) 258 { return ERR_PTR(-ENOSYS); } 259 260 static inline void kernfs_destroy_root(struct kernfs_root *root) { } 261 262 static inline struct sysfs_dirent * 263 kernfs_create_dir_ns(struct sysfs_dirent *parent, const char *name, void *priv, 264 const void *ns) 265 { return ERR_PTR(-ENOSYS); } 266 267 static inline struct sysfs_dirent * 268 kernfs_create_file_ns_key(struct sysfs_dirent *parent, const char *name, 269 umode_t mode, loff_t size, 270 const struct kernfs_ops *ops, void *priv, 271 const void *ns, struct lock_class_key *key) 272 { return ERR_PTR(-ENOSYS); } 273 274 static inline struct sysfs_dirent * 275 kernfs_create_link(struct sysfs_dirent *parent, const char *name, 276 struct sysfs_dirent *target) 277 { return ERR_PTR(-ENOSYS); } 278 279 static inline void kernfs_remove(struct sysfs_dirent *sd) { } 280 281 static inline int kernfs_remove_by_name_ns(struct sysfs_dirent *parent, 282 const char *name, const void *ns) 283 { return -ENOSYS; } 284 285 static inline int kernfs_rename_ns(struct sysfs_dirent *sd, 286 struct sysfs_dirent *new_parent, 287 const char *new_name, const void *new_ns) 288 { return -ENOSYS; } 289 290 static inline int kernfs_setattr(struct sysfs_dirent *sd, 291 const struct iattr *iattr) 292 { return -ENOSYS; } 293 294 static inline void kernfs_notify(struct sysfs_dirent *sd) { } 295 296 static inline const void *kernfs_super_ns(struct super_block *sb) 297 { return NULL; } 298 299 static inline struct dentry * 300 kernfs_mount_ns(struct file_system_type *fs_type, int flags, 301 struct kernfs_root *root, const void *ns) 302 { return ERR_PTR(-ENOSYS); } 303 304 static inline void kernfs_kill_sb(struct super_block *sb) { } 305 306 static inline void kernfs_init(void) { } 307 308 #endif /* CONFIG_SYSFS */ 309 310 static inline struct sysfs_dirent * 311 kernfs_find_and_get(struct sysfs_dirent *sd, const char *name) 312 { 313 return kernfs_find_and_get_ns(sd, name, NULL); 314 } 315 316 static inline struct sysfs_dirent * 317 kernfs_create_dir(struct sysfs_dirent *parent, const char *name, void *priv) 318 { 319 return kernfs_create_dir_ns(parent, name, priv, NULL); 320 } 321 322 static inline struct sysfs_dirent * 323 kernfs_create_file_ns(struct sysfs_dirent *parent, const char *name, 324 umode_t mode, loff_t size, const struct kernfs_ops *ops, 325 void *priv, const void *ns) 326 { 327 struct lock_class_key *key = NULL; 328 329 #ifdef CONFIG_DEBUG_LOCK_ALLOC 330 key = (struct lock_class_key *)&ops->lockdep_key; 331 #endif 332 return kernfs_create_file_ns_key(parent, name, mode, size, ops, priv, 333 ns, key); 334 } 335 336 static inline struct sysfs_dirent * 337 kernfs_create_file(struct sysfs_dirent *parent, const char *name, umode_t mode, 338 loff_t size, const struct kernfs_ops *ops, void *priv) 339 { 340 return kernfs_create_file_ns(parent, name, mode, size, ops, priv, NULL); 341 } 342 343 static inline int kernfs_remove_by_name(struct sysfs_dirent *parent, 344 const char *name) 345 { 346 return kernfs_remove_by_name_ns(parent, name, NULL); 347 } 348 349 static inline struct dentry * 350 kernfs_mount(struct file_system_type *fs_type, int flags, 351 struct kernfs_root *root) 352 { 353 return kernfs_mount_ns(fs_type, flags, root, NULL); 354 } 355 356 #endif /* __LINUX_KERNFS_H */ 357