.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
---|
1 | 2 | /* |
---|
2 | 3 | * kernfs.h - pseudo filesystem decoupled from vfs locking |
---|
3 | | - * |
---|
4 | | - * This file is released under the GPLv2. |
---|
5 | 4 | */ |
---|
6 | 5 | |
---|
7 | 6 | #ifndef __LINUX_KERNFS_H |
---|
.. | .. |
---|
27 | 26 | struct super_block; |
---|
28 | 27 | struct file_system_type; |
---|
29 | 28 | struct poll_table_struct; |
---|
| 29 | +struct fs_context; |
---|
30 | 30 | |
---|
| 31 | +struct kernfs_fs_context; |
---|
31 | 32 | struct kernfs_open_node; |
---|
32 | 33 | struct kernfs_iattrs; |
---|
33 | 34 | |
---|
.. | .. |
---|
37 | 38 | KERNFS_LINK = 0x0004, |
---|
38 | 39 | }; |
---|
39 | 40 | |
---|
40 | | -#define KERNFS_TYPE_MASK 0x000f |
---|
41 | | -#define KERNFS_FLAG_MASK ~KERNFS_TYPE_MASK |
---|
| 41 | +#define KERNFS_TYPE_MASK 0x000f |
---|
| 42 | +#define KERNFS_FLAG_MASK ~KERNFS_TYPE_MASK |
---|
| 43 | +#define KERNFS_MAX_USER_XATTRS 128 |
---|
| 44 | +#define KERNFS_USER_XATTR_SIZE_LIMIT (128 << 10) |
---|
42 | 45 | |
---|
43 | 46 | enum kernfs_node_flag { |
---|
44 | 47 | KERNFS_ACTIVATED = 0x0010, |
---|
.. | .. |
---|
63 | 66 | KERNFS_ROOT_CREATE_DEACTIVATED = 0x0001, |
---|
64 | 67 | |
---|
65 | 68 | /* |
---|
66 | | - * For regular flies, if the opener has CAP_DAC_OVERRIDE, open(2) |
---|
| 69 | + * For regular files, if the opener has CAP_DAC_OVERRIDE, open(2) |
---|
67 | 70 | * succeeds regardless of the RW permissions. sysfs had an extra |
---|
68 | 71 | * layer of enforcement where open(2) fails with -EACCES regardless |
---|
69 | 72 | * of CAP_DAC_OVERRIDE if the permission doesn't have the |
---|
.. | .. |
---|
78 | 81 | * fhandle to access nodes of the fs. |
---|
79 | 82 | */ |
---|
80 | 83 | KERNFS_ROOT_SUPPORT_EXPORTOP = 0x0004, |
---|
| 84 | + |
---|
| 85 | + /* |
---|
| 86 | + * Support user xattrs to be written to nodes rooted at this root. |
---|
| 87 | + */ |
---|
| 88 | + KERNFS_ROOT_SUPPORT_USER_XATTR = 0x0008, |
---|
81 | 89 | }; |
---|
82 | 90 | |
---|
83 | 91 | /* type-specific structures for kernfs_node union members */ |
---|
.. | .. |
---|
102 | 110 | struct kernfs_open_node *open; |
---|
103 | 111 | loff_t size; |
---|
104 | 112 | struct kernfs_node *notify_next; /* for kernfs_notify() */ |
---|
105 | | -}; |
---|
106 | | - |
---|
107 | | -/* represent a kernfs node */ |
---|
108 | | -union kernfs_node_id { |
---|
109 | | - struct { |
---|
110 | | - /* |
---|
111 | | - * blktrace will export this struct as a simplified 'struct |
---|
112 | | - * fid' (which is a big data struction), so userspace can use |
---|
113 | | - * it to find kernfs node. The layout must match the first two |
---|
114 | | - * fields of 'struct fid' exactly. |
---|
115 | | - */ |
---|
116 | | - u32 ino; |
---|
117 | | - u32 generation; |
---|
118 | | - }; |
---|
119 | | - u64 id; |
---|
120 | 113 | }; |
---|
121 | 114 | |
---|
122 | 115 | /* |
---|
.. | .. |
---|
155 | 148 | |
---|
156 | 149 | void *priv; |
---|
157 | 150 | |
---|
158 | | - union kernfs_node_id id; |
---|
| 151 | + /* |
---|
| 152 | + * 64bit unique ID. On 64bit ino setups, id is the ino. On 32bit, |
---|
| 153 | + * the low 32bits are ino and upper generation. |
---|
| 154 | + */ |
---|
| 155 | + u64 id; |
---|
| 156 | + |
---|
159 | 157 | unsigned short flags; |
---|
160 | 158 | umode_t mode; |
---|
161 | 159 | struct kernfs_iattrs *iattr; |
---|
| 160 | + |
---|
| 161 | + ANDROID_KABI_RESERVE(1); |
---|
162 | 162 | }; |
---|
163 | 163 | |
---|
164 | 164 | /* |
---|
.. | .. |
---|
169 | 169 | * kernfs_node parameter. |
---|
170 | 170 | */ |
---|
171 | 171 | struct kernfs_syscall_ops { |
---|
172 | | - int (*remount_fs)(struct kernfs_root *root, int *flags, char *data); |
---|
173 | 172 | int (*show_options)(struct seq_file *sf, struct kernfs_root *root); |
---|
174 | 173 | |
---|
175 | 174 | int (*mkdir)(struct kernfs_node *parent, const char *name, |
---|
.. | .. |
---|
193 | 192 | |
---|
194 | 193 | /* private fields, do not use outside kernfs proper */ |
---|
195 | 194 | struct idr ino_idr; |
---|
196 | | - u32 last_ino; |
---|
197 | | - u32 next_generation; |
---|
| 195 | + u32 last_id_lowbits; |
---|
| 196 | + u32 id_highbits; |
---|
198 | 197 | struct kernfs_syscall_ops *syscall_ops; |
---|
199 | 198 | |
---|
200 | 199 | /* list of kernfs_super_info of this root, protected by kernfs_mutex */ |
---|
201 | 200 | struct list_head supers; |
---|
202 | 201 | |
---|
203 | 202 | wait_queue_head_t deactivate_waitq; |
---|
| 203 | + |
---|
| 204 | + ANDROID_KABI_RESERVE(1); |
---|
204 | 205 | }; |
---|
205 | 206 | |
---|
206 | 207 | struct kernfs_open_file { |
---|
.. | .. |
---|
221 | 222 | bool mmapped:1; |
---|
222 | 223 | bool released:1; |
---|
223 | 224 | const struct vm_operations_struct *vm_ops; |
---|
| 225 | + |
---|
| 226 | + ANDROID_KABI_RESERVE(1); |
---|
224 | 227 | }; |
---|
225 | 228 | |
---|
226 | 229 | struct kernfs_ops { |
---|
.. | .. |
---|
282 | 285 | ANDROID_KABI_RESERVE(2); |
---|
283 | 286 | }; |
---|
284 | 287 | |
---|
| 288 | +/* |
---|
| 289 | + * The kernfs superblock creation/mount parameter context. |
---|
| 290 | + */ |
---|
| 291 | +struct kernfs_fs_context { |
---|
| 292 | + struct kernfs_root *root; /* Root of the hierarchy being mounted */ |
---|
| 293 | + void *ns_tag; /* Namespace tag of the mount (or NULL) */ |
---|
| 294 | + unsigned long magic; /* File system specific magic number */ |
---|
| 295 | + |
---|
| 296 | + /* The following are set/used by kernfs_mount() */ |
---|
| 297 | + bool new_sb_created; /* Set to T if we allocated a new sb */ |
---|
| 298 | +}; |
---|
| 299 | + |
---|
285 | 300 | #ifdef CONFIG_KERNFS |
---|
286 | 301 | |
---|
287 | 302 | static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn) |
---|
288 | 303 | { |
---|
289 | 304 | return kn->flags & KERNFS_TYPE_MASK; |
---|
| 305 | +} |
---|
| 306 | + |
---|
| 307 | +static inline ino_t kernfs_id_ino(u64 id) |
---|
| 308 | +{ |
---|
| 309 | + /* id is ino if ino_t is 64bit; otherwise, low 32bits */ |
---|
| 310 | + if (sizeof(ino_t) >= sizeof(u64)) |
---|
| 311 | + return id; |
---|
| 312 | + else |
---|
| 313 | + return (u32)id; |
---|
| 314 | +} |
---|
| 315 | + |
---|
| 316 | +static inline u32 kernfs_id_gen(u64 id) |
---|
| 317 | +{ |
---|
| 318 | + /* gen is fixed at 1 if ino_t is 64bit; otherwise, high 32bits */ |
---|
| 319 | + if (sizeof(ino_t) >= sizeof(u64)) |
---|
| 320 | + return 1; |
---|
| 321 | + else |
---|
| 322 | + return id >> 32; |
---|
| 323 | +} |
---|
| 324 | + |
---|
| 325 | +static inline ino_t kernfs_ino(struct kernfs_node *kn) |
---|
| 326 | +{ |
---|
| 327 | + return kernfs_id_ino(kn->id); |
---|
| 328 | +} |
---|
| 329 | + |
---|
| 330 | +static inline ino_t kernfs_gen(struct kernfs_node *kn) |
---|
| 331 | +{ |
---|
| 332 | + return kernfs_id_gen(kn->id); |
---|
290 | 333 | } |
---|
291 | 334 | |
---|
292 | 335 | /** |
---|
.. | .. |
---|
368 | 411 | struct poll_table_struct *pt); |
---|
369 | 412 | void kernfs_notify(struct kernfs_node *kn); |
---|
370 | 413 | |
---|
| 414 | +int kernfs_xattr_get(struct kernfs_node *kn, const char *name, |
---|
| 415 | + void *value, size_t size); |
---|
| 416 | +int kernfs_xattr_set(struct kernfs_node *kn, const char *name, |
---|
| 417 | + const void *value, size_t size, int flags); |
---|
| 418 | + |
---|
371 | 419 | const void *kernfs_super_ns(struct super_block *sb); |
---|
372 | | -struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, |
---|
373 | | - struct kernfs_root *root, unsigned long magic, |
---|
374 | | - bool *new_sb_created, const void *ns); |
---|
| 420 | +int kernfs_get_tree(struct fs_context *fc); |
---|
| 421 | +void kernfs_free_fs_context(struct fs_context *fc); |
---|
375 | 422 | void kernfs_kill_sb(struct super_block *sb); |
---|
376 | | -struct super_block *kernfs_pin_sb(struct kernfs_root *root, const void *ns); |
---|
377 | 423 | |
---|
378 | 424 | void kernfs_init(void); |
---|
379 | 425 | |
---|
380 | | -struct kernfs_node *kernfs_get_node_by_id(struct kernfs_root *root, |
---|
381 | | - const union kernfs_node_id *id); |
---|
| 426 | +struct kernfs_node *kernfs_find_and_get_node_by_id(struct kernfs_root *root, |
---|
| 427 | + u64 id); |
---|
382 | 428 | #else /* CONFIG_KERNFS */ |
---|
383 | 429 | |
---|
384 | 430 | static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn) |
---|
.. | .. |
---|
472 | 518 | |
---|
473 | 519 | static inline void kernfs_notify(struct kernfs_node *kn) { } |
---|
474 | 520 | |
---|
| 521 | +static inline int kernfs_xattr_get(struct kernfs_node *kn, const char *name, |
---|
| 522 | + void *value, size_t size) |
---|
| 523 | +{ return -ENOSYS; } |
---|
| 524 | + |
---|
| 525 | +static inline int kernfs_xattr_set(struct kernfs_node *kn, const char *name, |
---|
| 526 | + const void *value, size_t size, int flags) |
---|
| 527 | +{ return -ENOSYS; } |
---|
| 528 | + |
---|
475 | 529 | static inline const void *kernfs_super_ns(struct super_block *sb) |
---|
476 | 530 | { return NULL; } |
---|
477 | 531 | |
---|
478 | | -static inline struct dentry * |
---|
479 | | -kernfs_mount_ns(struct file_system_type *fs_type, int flags, |
---|
480 | | - struct kernfs_root *root, unsigned long magic, |
---|
481 | | - bool *new_sb_created, const void *ns) |
---|
482 | | -{ return ERR_PTR(-ENOSYS); } |
---|
| 532 | +static inline int kernfs_get_tree(struct fs_context *fc) |
---|
| 533 | +{ return -ENOSYS; } |
---|
| 534 | + |
---|
| 535 | +static inline void kernfs_free_fs_context(struct fs_context *fc) { } |
---|
483 | 536 | |
---|
484 | 537 | static inline void kernfs_kill_sb(struct super_block *sb) { } |
---|
485 | 538 | |
---|
.. | .. |
---|
493 | 546 | * @buf: buffer to copy @kn's name into |
---|
494 | 547 | * @buflen: size of @buf |
---|
495 | 548 | * |
---|
496 | | - * Builds and returns the full path of @kn in @buf of @buflen bytes. The |
---|
497 | | - * path is built from the end of @buf so the returned pointer usually |
---|
498 | | - * doesn't match @buf. If @buf isn't long enough, @buf is nul terminated |
---|
499 | | - * and %NULL is returned. |
---|
| 549 | + * If @kn is NULL result will be "(null)". |
---|
| 550 | + * |
---|
| 551 | + * Returns the length of the full path. If the full length is equal to or |
---|
| 552 | + * greater than @buflen, @buf contains the truncated path with the trailing |
---|
| 553 | + * '\0'. On error, -errno is returned. |
---|
500 | 554 | */ |
---|
501 | 555 | static inline int kernfs_path(struct kernfs_node *kn, char *buf, size_t buflen) |
---|
502 | 556 | { |
---|
.. | .. |
---|
559 | 613 | const char *new_name) |
---|
560 | 614 | { |
---|
561 | 615 | return kernfs_rename_ns(kn, new_parent, new_name, NULL); |
---|
562 | | -} |
---|
563 | | - |
---|
564 | | -static inline struct dentry * |
---|
565 | | -kernfs_mount(struct file_system_type *fs_type, int flags, |
---|
566 | | - struct kernfs_root *root, unsigned long magic, |
---|
567 | | - bool *new_sb_created) |
---|
568 | | -{ |
---|
569 | | - return kernfs_mount_ns(fs_type, flags, root, |
---|
570 | | - magic, new_sb_created, NULL); |
---|
571 | 616 | } |
---|
572 | 617 | |
---|
573 | 618 | #endif /* __LINUX_KERNFS_H */ |
---|