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 22 struct 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 34 struct 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 */ 71 static 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 */ 85 struct 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 107 static inline bool kernfs_root_is_locked(const struct kernfs_node *kn) 108 { 109 return lockdep_is_held(&kernfs_root(kn)->kernfs_rwsem); 110 } 111 112 static 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 117 static 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 122 static 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 139 static 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 146 static inline void kernfs_set_rev(struct kernfs_node *parent, 147 struct dentry *dentry) 148 { 149 dentry->d_time = parent->dir.rev; 150 } 151 152 static inline void kernfs_inc_rev(struct kernfs_node *parent) 153 { 154 parent->dir.rev++; 155 } 156 157 static 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 165 extern const struct super_operations kernfs_sops; 166 extern struct kmem_cache *kernfs_node_cache, *kernfs_iattrs_cache; 167 168 /* 169 * inode.c 170 */ 171 extern const struct xattr_handler * const kernfs_xattr_handlers[]; 172 void kernfs_evict_inode(struct inode *inode); 173 int kernfs_iop_permission(struct mnt_idmap *idmap, 174 struct inode *inode, int mask); 175 int kernfs_iop_setattr(struct mnt_idmap *idmap, struct dentry *dentry, 176 struct iattr *iattr); 177 int kernfs_iop_getattr(struct mnt_idmap *idmap, 178 const struct path *path, struct kstat *stat, 179 u32 request_mask, unsigned int query_flags); 180 ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size); 181 int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr); 182 183 /* 184 * dir.c 185 */ 186 extern const struct dentry_operations kernfs_dops; 187 extern const struct file_operations kernfs_dir_fops; 188 extern const struct inode_operations kernfs_dir_iops; 189 190 struct kernfs_node *kernfs_get_active(struct kernfs_node *kn); 191 void kernfs_put_active(struct kernfs_node *kn); 192 int kernfs_add_one(struct kernfs_node *kn); 193 struct 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 */ 201 extern const struct file_operations kernfs_file_fops; 202 203 bool kernfs_should_drain_open_files(struct kernfs_node *kn); 204 void kernfs_drain_open_files(struct kernfs_node *kn); 205 206 /* 207 * symlink.c 208 */ 209 extern const struct inode_operations kernfs_symlink_iops; 210 211 /* 212 * kernfs locks 213 */ 214 extern struct kernfs_global_locks *kernfs_locks; 215 #endif /* __KERNFS_INTERNAL_H */ 216