]> Git Repo - linux.git/blame - fs/sysfs/sysfs.h
sysfs, kernfs: add sysfs_dirent->s_attr.size
[linux.git] / fs / sysfs / sysfs.h
CommitLineData
6d66f5cd
TH
1/*
2 * fs/sysfs/sysfs.h - sysfs internal header file
3 *
4 * Copyright (c) 2001-3 Patrick Mochel
5 * Copyright (c) 2007 SUSE Linux Products GmbH
6 * Copyright (c) 2007 Tejun Heo <[email protected]>
7 *
8 * This file is released under the GPLv2.
9 */
10
846f9974 11#include <linux/lockdep.h>
57cc7215 12#include <linux/kobject_ns.h>
ddd29ec6 13#include <linux/fs.h>
4f72c0ca 14#include <linux/rbtree.h>
ddd29ec6 15
85a4ffad
TH
16struct sysfs_open_dirent;
17
59f69015 18/* type-specific structures for sysfs_dirent->s_* union members */
3e519038 19struct sysfs_elem_dir {
54d20f00 20 unsigned long subdirs;
4e4d6d86
EB
21 /* children rbtree starts here and goes through sd->s_rb */
22 struct rb_root children;
3e519038
TH
23};
24
25struct sysfs_elem_symlink {
59f69015 26 struct sysfs_dirent *target_sd;
3e519038
TH
27};
28
29struct sysfs_elem_attr {
f6acf8bb 30 const struct kernfs_ops *ops;
85a4ffad 31 struct sysfs_open_dirent *open;
471bd7b7 32 loff_t size;
3e519038
TH
33};
34
ddd29ec6
DQ
35struct sysfs_inode_attrs {
36 struct iattr ia_iattr;
37 void *ia_secdata;
38 u32 ia_secdata_len;
39};
40
0ab66088 41/*
59f69015
TH
42 * sysfs_dirent - the building block of sysfs hierarchy. Each and
43 * every sysfs node is represented by single sysfs_dirent.
44 *
0ab66088
TH
45 * As long as s_count reference is held, the sysfs_dirent itself is
46 * accessible. Dereferencing s_elem or any other outer entity
47 * requires s_active reference.
48 */
d56c3eae
AR
49struct sysfs_dirent {
50 atomic_t s_count;
8619f979 51 atomic_t s_active;
846f9974
EB
52#ifdef CONFIG_DEBUG_LOCK_ALLOC
53 struct lockdep_map dep_map;
54#endif
59f69015 55 struct sysfs_dirent *s_parent;
59f69015 56 const char *s_name;
3e519038 57
4e4d6d86 58 struct rb_node s_rb;
4f72c0ca 59
58f2a4c7
MP
60 union {
61 struct completion *completion;
62 struct sysfs_dirent *removed_list;
63 } u;
64
be867b19 65 const void *s_ns; /* namespace tag */
4e4d6d86 66 unsigned int s_hash; /* ns + name hash */
3e519038 67 union {
b1fc3d61
TH
68 struct sysfs_elem_dir s_dir;
69 struct sysfs_elem_symlink s_symlink;
70 struct sysfs_elem_attr s_attr;
b1fc3d61 71 };
3e519038 72
7c6e2d36
TH
73 void *priv;
74
15a33824 75 unsigned short s_flags;
2c3a908b 76 umode_t s_mode;
cafa6b5d 77 unsigned int s_ino;
ddd29ec6 78 struct sysfs_inode_attrs *s_iattr;
d56c3eae 79};
1da177e4 80
59f69015 81#define SD_DEACTIVATED_BIAS INT_MIN
0ab66088 82
59f69015 83#define SYSFS_TYPE_MASK 0x00ff
dc2f75f0
TH
84#define SYSFS_DIR 0x0001
85#define SYSFS_KOBJ_ATTR 0x0002
86#define SYSFS_KOBJ_BIN_ATTR 0x0004
87#define SYSFS_KOBJ_LINK 0x0008
59f69015 88#define SYSFS_COPY_NAME (SYSFS_DIR | SYSFS_KOBJ_LINK)
a2db6842 89#define SYSFS_ACTIVE_REF (SYSFS_KOBJ_ATTR | SYSFS_KOBJ_BIN_ATTR)
59f69015 90
c84a3b27
TH
91#define SYSFS_FLAG_MASK ~SYSFS_TYPE_MASK
92#define SYSFS_FLAG_NS 0x01000
15a33824 93#define SYSFS_FLAG_REMOVED 0x02000
f6acf8bb
TH
94#define SYSFS_FLAG_HAS_SEQ_SHOW 0x04000
95#define SYSFS_FLAG_HAS_MMAP 0x08000
59f69015
TH
96
97static inline unsigned int sysfs_type(struct sysfs_dirent *sd)
98{
99 return sd->s_flags & SYSFS_TYPE_MASK;
100}
101
846f9974 102#ifdef CONFIG_DEBUG_LOCK_ALLOC
785a162d 103
846f9974
EB
104#define sysfs_dirent_init_lockdep(sd) \
105do { \
7c6e2d36 106 struct attribute *attr = sd->priv; \
6992f533
EB
107 struct lock_class_key *key = attr->key; \
108 if (!key) \
109 key = &attr->skey; \
846f9974 110 \
6992f533 111 lockdep_init_map(&sd->dep_map, "s_active", key, 0); \
2c3a908b 112} while (0)
785a162d
TH
113
114/* Test for attributes that want to ignore lockdep for read-locking */
115static inline bool sysfs_ignore_lockdep(struct sysfs_dirent *sd)
116{
7c6e2d36 117 struct attribute *attr = sd->priv;
672f76a8
TH
118 int type = sysfs_type(sd);
119
120 return (type == SYSFS_KOBJ_ATTR || type == SYSFS_KOBJ_BIN_ATTR) &&
7c6e2d36 121 attr->ignore_lockdep;
785a162d
TH
122}
123
846f9974 124#else
785a162d 125
2c3a908b 126#define sysfs_dirent_init_lockdep(sd) do {} while (0)
785a162d
TH
127
128static inline bool sysfs_ignore_lockdep(struct sysfs_dirent *sd)
129{
130 return true;
131}
132
846f9974
EB
133#endif
134
59f69015
TH
135/*
136 * Context structure to be used while adding/removing nodes.
137 */
fb6896da 138struct sysfs_addrm_cxt {
fb6896da 139 struct sysfs_dirent *removed;
fb6896da
TH
140};
141
59f69015
TH
142/*
143 * mount.c
144 */
be867b19
SH
145
146/*
c84a3b27
TH
147 * Each sb is associated with one namespace tag, currently the network
148 * namespace of the task which mounted this sysfs instance. If multiple
149 * tags become necessary, make the following an array and compare
150 * sysfs_dirent tag against every entry.
be867b19 151 */
9e7fdd25 152struct sysfs_super_info {
c84a3b27 153 void *ns;
9e7fdd25
EB
154};
155#define sysfs_info(SB) ((struct sysfs_super_info *)(SB->s_fs_info))
51225039 156extern struct sysfs_dirent sysfs_root;
e18b890b 157extern struct kmem_cache *sysfs_dir_cachep;
1da177e4 158
59f69015
TH
159/*
160 * dir.c
161 */
3007e997 162extern struct mutex sysfs_mutex;
0cae60f9 163extern spinlock_t sysfs_symlink_target_lock;
469796d1 164extern const struct dentry_operations sysfs_dentry_ops;
59f69015 165
4b6f5d20 166extern const struct file_operations sysfs_dir_operations;
c5ef1c42 167extern const struct inode_operations sysfs_dir_inode_operations;
1da177e4 168
e72ceb8c
EB
169struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd);
170void sysfs_put_active(struct sysfs_dirent *sd);
d69ac5a0 171void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt);
d1c1459e 172void sysfs_warn_dup(struct sysfs_dirent *parent, const char *name);
d69ac5a0
TH
173int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd,
174 struct sysfs_dirent *parent_sd);
175int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd,
176 struct sysfs_dirent *parent_sd);
59f69015
TH
177void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt);
178
179struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
cfec0bc8
TH
180 const unsigned char *name,
181 const void *ns);
59f69015
TH
182struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type);
183
184void release_sysfs_dirent(struct sysfs_dirent *sd);
185
f1282c84 186static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd)
1da177e4 187{
0ab66088
TH
188 if (sd) {
189 WARN_ON(!atomic_read(&sd->s_count));
190 atomic_inc(&sd->s_count);
191 }
192 return sd;
1da177e4 193}
f1282c84 194#define sysfs_get(sd) __sysfs_get(sd)
1da177e4 195
f1282c84 196static inline void __sysfs_put(struct sysfs_dirent *sd)
1da177e4 197{
0ab66088
TH
198 if (sd && atomic_dec_and_test(&sd->s_count))
199 release_sysfs_dirent(sd);
200}
f1282c84 201#define sysfs_put(sd) __sysfs_put(sd)
59f69015
TH
202
203/*
204 * inode.c
205 */
fac2622b 206struct inode *sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd);
01cd9fef 207void sysfs_evict_inode(struct inode *inode);
10556cb2 208int sysfs_permission(struct inode *inode, int mask);
59f69015 209int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
2c3a908b
GKH
210int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
211 struct kstat *stat);
ddd29ec6 212int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value,
2c3a908b 213 size_t size, int flags);
e0bf68dd 214int sysfs_inode_init(void);
59f69015
TH
215
216/*
217 * file.c
218 */
c6fb4495 219extern const struct file_operations kernfs_file_operations;
59f69015
TH
220
221int sysfs_add_file(struct sysfs_dirent *dir_sd,
222 const struct attribute *attr, int type);
223
58292cbe
TH
224int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd,
225 const struct attribute *attr, int type,
226 umode_t amode, const void *ns);
73d97146
TH
227void sysfs_unmap_bin_file(struct sysfs_dirent *sd);
228
59f69015
TH
229/*
230 * symlink.c
231 */
232extern const struct inode_operations sysfs_symlink_inode_operations;
0bb8f3d6
RW
233int sysfs_create_link_sd(struct sysfs_dirent *sd, struct kobject *target,
234 const char *name);
This page took 0.824601 seconds and 4 git commands to generate.