FILE
kernfs-internal.h
File preview with syntax highlighting.
linux-6.19.14/fs/kernfs/kernfs-internal.h
1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * fs/kernfs/kernfs-internal.h - kernfs internal header file 4 * 5 * Copyright (c) 2001-3 Patrick Mochel 6 * Copyright (c) 2007 SUSE Linux Products GmbH 7 * Copyright (c) 2007, 2013 Tejun Heo <teheo@suse.de> 8 */ 9 10#ifndef __KERNFS_INTERNAL_H 11#define __KERNFS_INTERNAL_H 12 13#include <linux/lockdep.h> 14#include <linux/fs.h> 15#include <linux/mutex.h> 16#include <linux/rwsem.h> 17#include <linux/xattr.h> 18 19#include <linux/kernfs.h> 20#include <linux/fs_context.h> 21 22struct kernfs_iattrs { 23 kuid_t ia_uid; 24 kgid_t ia_gid; 25 struct timespec64 ia_atime; 26 struct timespec64 ia_mtime; 27 struct timespec64 ia_ctime; 28 29 struct simple_xattrs xattrs; 30 atomic_t nr_user_xattrs; 31 atomic_t user_xattr_size; 32}; 33 34struct kernfs_root { 35 /* published fields */ 36 struct kernfs_node *kn; 37 unsigned int flags; /* KERNFS_ROOT_* flags */ 38 39 /* private fields, do not use outside kernfs proper */ 40 struct idr ino_idr; 41 spinlock_t kernfs_idr_lock; /* root->ino_idr */ 42 u32 last_id_lowbits; 43 u32 id_highbits; 44 struct kernfs_syscall_ops *syscall_ops; 45 46 /* list of kernfs_super_info of this root, protected by kernfs_rwsem */ 47 struct list_head supers; 48 49 wait_queue_head_t deactivate_waitq; 50 struct rw_semaphore kernfs_rwsem; 51 struct rw_semaphore kernfs_iattr_rwsem; 52 struct rw_semaphore kernfs_supers_rwsem; 53 54 /* kn->parent and kn->name */ 55 rwlock_t kernfs_rename_lock; 56 57 struct rcu_head rcu; 58}; 59 60/* +1 to avoid triggering overflow warning when negating it */ 61#define KN_DEACTIVATED_BIAS (INT_MIN + 1) 62 63/* KERNFS_TYPE_MASK and types are defined in include/linux/kernfs.h */ 64 65/** 66 * kernfs_root - find out the kernfs_root a kernfs_node belongs to 67 * @kn: kernfs_node of interest 68 * 69 * Return: the kernfs_root @kn belongs to. 70 */ 71static inline struct kernfs_root *kernfs_root(const struct kernfs_node *kn) 72{ 73 const struct kernfs_node *knp; 74 /* if parent exists, it's always a dir; otherwise, @sd is a dir */ 75 guard(rcu)(); 76 knp = rcu_dereference(kn->__parent); 77 if (knp) 78 kn = knp; 79 return kn->dir.root; 80} 81 82/* 83 * mount.c 84 */ 85struct kernfs_super_info { 86 struct super_block *sb; 87 88 /* 89 * The root associated with this super_block. Each super_block is 90 * identified by the root and ns it's associated with. 91 */ 92 struct kernfs_root *root; 93 94 /* 95 * Each sb is associated with one namespace tag, currently the 96 * network namespace of the task which mounted this kernfs 97 * instance. If multiple tags become necessary, make the following 98 * an array and compare kernfs_node tag against every entry. 99 */ 100 const void *ns; 101 102 /* anchored at kernfs_root->supers, protected by kernfs_rwsem */ 103 struct list_head node; 104}; 105#define kernfs_info(SB) ((struct kernfs_super_info *)(SB->s_fs_info)) 106 107static inline bool kernfs_root_is_locked(const struct kernfs_node *kn) 108{ 109 return lockdep_is_held(&kernfs_root(kn)->kernfs_rwsem); 110} 111 112static inline bool kernfs_rename_is_locked(const struct kernfs_node *kn) 113{ 114 return lockdep_is_held(&kernfs_root(kn)->kernfs_rename_lock); 115} 116 117static inline const char *kernfs_rcu_name(const struct kernfs_node *kn) 118{ 119 return rcu_dereference_check(kn->name, kernfs_root_is_locked(kn)); 120} 121 122static inline struct kernfs_node *kernfs_parent(const struct kernfs_node *kn) 123{ 124 /* 125 * The kernfs_node::__parent remains valid within a RCU section. The kn 126 * can be reparented (and renamed) which changes the entry. This can be 127 * avoided by locking kernfs_root::kernfs_rwsem or 128 * kernfs_root::kernfs_rename_lock. 129 * Both locks can be used to obtain a reference on __parent. Once the 130 * reference count reaches 0 then the node is about to be freed 131 * and can not be renamed (or become a different parent) anymore. 132 */ 133 return rcu_dereference_check(kn->__parent, 134 kernfs_root_is_locked(kn) || 135 kernfs_rename_is_locked(kn) || 136 !atomic_read(&kn->count)); 137} 138 139static inline struct kernfs_node *kernfs_dentry_node(struct dentry *dentry) 140{ 141 if (d_really_is_negative(dentry)) 142 return NULL; 143 return d_inode(dentry)->i_private; 144} 145 146static inline void kernfs_set_rev(struct kernfs_node *parent, 147 struct dentry *dentry) 148{ 149 dentry->d_time = parent->dir.rev; 150} 151 152static inline void kernfs_inc_rev(struct kernfs_node *parent) 153{ 154 parent->dir.rev++; 155} 156 157static inline bool kernfs_dir_changed(struct kernfs_node *parent, 158 struct dentry *dentry) 159{ 160 if (parent->dir.rev != dentry->d_time) 161 return true; 162 return false; 163} 164 165extern const struct super_operations kernfs_sops; 166extern struct kmem_cache *kernfs_node_cache, *kernfs_iattrs_cache; 167 168/* 169 * inode.c 170 */ 171extern const struct xattr_handler * const kernfs_xattr_handlers[]; 172void kernfs_evict_inode(struct inode *inode); 173int kernfs_iop_permission(struct mnt_idmap *idmap, 174 struct inode *inode, int mask); 175int kernfs_iop_setattr(struct mnt_idmap *idmap, struct dentry *dentry, 176 struct iattr *iattr); 177int kernfs_iop_getattr(struct mnt_idmap *idmap, 178 const struct path *path, struct kstat *stat, 179 u32 request_mask, unsigned int query_flags); 180ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size); 181int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr); 182 183/* 184 * dir.c 185 */ 186extern const struct dentry_operations kernfs_dops; 187extern const struct file_operations kernfs_dir_fops; 188extern const struct inode_operations kernfs_dir_iops; 189 190struct kernfs_node *kernfs_get_active(struct kernfs_node *kn); 191void kernfs_put_active(struct kernfs_node *kn); 192int kernfs_add_one(struct kernfs_node *kn); 193struct kernfs_node *kernfs_new_node(struct kernfs_node *parent, 194 const char *name, umode_t mode, 195 kuid_t uid, kgid_t gid, 196 unsigned flags); 197 198/* 199 * file.c 200 */ 201extern const struct file_operations kernfs_file_fops; 202 203bool kernfs_should_drain_open_files(struct kernfs_node *kn); 204void kernfs_drain_open_files(struct kernfs_node *kn); 205 206/* 207 * symlink.c 208 */ 209extern const struct inode_operations kernfs_symlink_iops; 210 211/* 212 * kernfs locks 213 */ 214extern struct kernfs_global_locks *kernfs_locks; 215#endif /* __KERNFS_INTERNAL_H */
~/
Read-only file preview.