Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 : : /* -*- mode: c; c-basic-offset:8; -*- 3 : : * vim: noexpandtab sw=8 ts=8 sts=0: 4 : : * 5 : : * configfs_internal.h - Internal stuff for configfs 6 : : * 7 : : * Based on sysfs: 8 : : * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel 9 : : * 10 : : * configfs Copyright (C) 2005 Oracle. All rights reserved. 11 : : */ 12 : : 13 : : #ifdef pr_fmt 14 : : #undef pr_fmt 15 : : #endif 16 : : 17 : : #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 18 : : 19 : : #include <linux/slab.h> 20 : : #include <linux/list.h> 21 : : #include <linux/spinlock.h> 22 : : 23 : : struct configfs_fragment { 24 : : atomic_t frag_count; 25 : : struct rw_semaphore frag_sem; 26 : : bool frag_dead; 27 : : }; 28 : : 29 : : void put_fragment(struct configfs_fragment *); 30 : : struct configfs_fragment *get_fragment(struct configfs_fragment *); 31 : : 32 : : struct configfs_dirent { 33 : : atomic_t s_count; 34 : : int s_dependent_count; 35 : : struct list_head s_sibling; 36 : : struct list_head s_children; 37 : : int s_links; 38 : : void * s_element; 39 : : int s_type; 40 : : umode_t s_mode; 41 : : struct dentry * s_dentry; 42 : : struct iattr * s_iattr; 43 : : #ifdef CONFIG_LOCKDEP 44 : : int s_depth; 45 : : #endif 46 : : struct configfs_fragment *s_frag; 47 : : }; 48 : : 49 : : #define CONFIGFS_ROOT 0x0001 50 : : #define CONFIGFS_DIR 0x0002 51 : : #define CONFIGFS_ITEM_ATTR 0x0004 52 : : #define CONFIGFS_ITEM_BIN_ATTR 0x0008 53 : : #define CONFIGFS_ITEM_LINK 0x0020 54 : : #define CONFIGFS_USET_DIR 0x0040 55 : : #define CONFIGFS_USET_DEFAULT 0x0080 56 : : #define CONFIGFS_USET_DROPPING 0x0100 57 : : #define CONFIGFS_USET_IN_MKDIR 0x0200 58 : : #define CONFIGFS_USET_CREATING 0x0400 59 : : #define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR | CONFIGFS_ITEM_BIN_ATTR) 60 : : 61 : : extern struct mutex configfs_symlink_mutex; 62 : : extern spinlock_t configfs_dirent_lock; 63 : : 64 : : extern struct kmem_cache *configfs_dir_cachep; 65 : : 66 : : extern int configfs_is_root(struct config_item *item); 67 : : 68 : : extern struct inode * configfs_new_inode(umode_t mode, struct configfs_dirent *, struct super_block *); 69 : : extern struct inode *configfs_create(struct dentry *, umode_t mode); 70 : : 71 : : extern int configfs_create_file(struct config_item *, const struct configfs_attribute *); 72 : : extern int configfs_create_bin_file(struct config_item *, 73 : : const struct configfs_bin_attribute *); 74 : : extern int configfs_make_dirent(struct configfs_dirent *, struct dentry *, 75 : : void *, umode_t, int, struct configfs_fragment *); 76 : : extern int configfs_dirent_is_ready(struct configfs_dirent *); 77 : : 78 : : extern void configfs_hash_and_remove(struct dentry * dir, const char * name); 79 : : 80 : : extern const unsigned char * configfs_get_name(struct configfs_dirent *sd); 81 : : extern void configfs_drop_dentry(struct configfs_dirent *sd, struct dentry *parent); 82 : : extern int configfs_setattr(struct dentry *dentry, struct iattr *iattr); 83 : : 84 : : extern struct dentry *configfs_pin_fs(void); 85 : : extern void configfs_release_fs(void); 86 : : 87 : : extern const struct file_operations configfs_dir_operations; 88 : : extern const struct file_operations configfs_file_operations; 89 : : extern const struct file_operations configfs_bin_file_operations; 90 : : extern const struct inode_operations configfs_dir_inode_operations; 91 : : extern const struct inode_operations configfs_root_inode_operations; 92 : : extern const struct inode_operations configfs_symlink_inode_operations; 93 : : extern const struct dentry_operations configfs_dentry_ops; 94 : : 95 : : extern int configfs_symlink(struct inode *dir, struct dentry *dentry, 96 : : const char *symname); 97 : : extern int configfs_unlink(struct inode *dir, struct dentry *dentry); 98 : : 99 : : int configfs_create_link(struct configfs_dirent *target, struct dentry *parent, 100 : : struct dentry *dentry, char *body); 101 : : 102 : : static inline struct config_item * to_item(struct dentry * dentry) 103 : : { 104 : 0 : struct configfs_dirent * sd = dentry->d_fsdata; 105 : 0 : return ((struct config_item *) sd->s_element); 106 : : } 107 : : 108 : : static inline struct configfs_attribute * to_attr(struct dentry * dentry) 109 : : { 110 : 0 : struct configfs_dirent * sd = dentry->d_fsdata; 111 : 0 : return ((struct configfs_attribute *) sd->s_element); 112 : : } 113 : : 114 : : static inline struct configfs_bin_attribute *to_bin_attr(struct dentry *dentry) 115 : : { 116 : : struct configfs_attribute *attr = to_attr(dentry); 117 : : 118 : : return container_of(attr, struct configfs_bin_attribute, cb_attr); 119 : : } 120 : : 121 : 0 : static inline struct config_item *configfs_get_config_item(struct dentry *dentry) 122 : : { 123 : : struct config_item * item = NULL; 124 : : 125 : : spin_lock(&dentry->d_lock); 126 [ # # ]: 0 : if (!d_unhashed(dentry)) { 127 : 0 : struct configfs_dirent * sd = dentry->d_fsdata; 128 : 0 : item = config_item_get(sd->s_element); 129 : : } 130 : : spin_unlock(&dentry->d_lock); 131 : : 132 : 0 : return item; 133 : : } 134 : : 135 : 0 : static inline void release_configfs_dirent(struct configfs_dirent * sd) 136 : : { 137 [ # # ]: 0 : if (!(sd->s_type & CONFIGFS_ROOT)) { 138 : 0 : kfree(sd->s_iattr); 139 : 0 : put_fragment(sd->s_frag); 140 : 0 : kmem_cache_free(configfs_dir_cachep, sd); 141 : : } 142 : 0 : } 143 : : 144 : 414 : static inline struct configfs_dirent * configfs_get(struct configfs_dirent * sd) 145 : : { 146 [ + - ]: 414 : if (sd) { 147 [ - + ]: 414 : WARN_ON(!atomic_read(&sd->s_count)); 148 : 414 : atomic_inc(&sd->s_count); 149 : : } 150 : 414 : return sd; 151 : : } 152 : : 153 : 0 : static inline void configfs_put(struct configfs_dirent * sd) 154 : : { 155 [ # # ]: 0 : WARN_ON(!atomic_read(&sd->s_count)); 156 [ # # ]: 0 : if (atomic_dec_and_test(&sd->s_count)) 157 : 0 : release_configfs_dirent(sd); 158 : 0 : } 159 : :