]> git.karo-electronics.de Git - karo-tx-linux.git/blob - include/linux/kernfs.h
sysfs, kernfs: revamp sysfs_dirent active_ref lockdep annotation
[karo-tx-linux.git] / include / linux / kernfs.h
1 /*
2  * kernfs.h - pseudo filesystem decoupled from vfs locking
3  *
4  * This file is released under the GPLv2.
5  */
6
7 #ifndef __LINUX_KERNFS_H
8 #define __LINUX_KERNFS_H
9
10 #include <linux/kernel.h>
11 #include <linux/err.h>
12 #include <linux/list.h>
13 #include <linux/mutex.h>
14 #include <linux/lockdep.h>
15
16 struct file;
17 struct iattr;
18 struct seq_file;
19 struct vm_area_struct;
20
21 struct sysfs_dirent;
22
23 struct sysfs_open_file {
24         /* published fields */
25         struct sysfs_dirent     *sd;
26         struct file             *file;
27
28         /* private fields, do not use outside kernfs proper */
29         struct mutex            mutex;
30         int                     event;
31         struct list_head        list;
32
33         bool                    mmapped;
34         const struct vm_operations_struct *vm_ops;
35 };
36
37 struct kernfs_ops {
38         /*
39          * Read is handled by either seq_file or raw_read().
40          *
41          * If seq_show() is present, seq_file path is active.  Other seq
42          * operations are optional and if not implemented, the behavior is
43          * equivalent to single_open().  @sf->private points to the
44          * associated sysfs_open_file.
45          *
46          * read() is bounced through kernel buffer and a read larger than
47          * PAGE_SIZE results in partial operation of PAGE_SIZE.
48          */
49         int (*seq_show)(struct seq_file *sf, void *v);
50
51         void *(*seq_start)(struct seq_file *sf, loff_t *ppos);
52         void *(*seq_next)(struct seq_file *sf, void *v, loff_t *ppos);
53         void (*seq_stop)(struct seq_file *sf, void *v);
54
55         ssize_t (*read)(struct sysfs_open_file *of, char *buf, size_t bytes,
56                         loff_t off);
57
58         /*
59          * write() is bounced through kernel buffer and a write larger than
60          * PAGE_SIZE results in partial operation of PAGE_SIZE.
61          */
62         ssize_t (*write)(struct sysfs_open_file *of, char *buf, size_t bytes,
63                          loff_t off);
64
65         int (*mmap)(struct sysfs_open_file *of, struct vm_area_struct *vma);
66
67 #ifdef CONFIG_DEBUG_LOCK_ALLOC
68         struct lock_class_key   lockdep_key;
69 #endif
70 };
71
72 #ifdef CONFIG_SYSFS
73
74 struct sysfs_dirent *kernfs_create_dir_ns(struct sysfs_dirent *parent,
75                                           const char *name, void *priv,
76                                           const void *ns);
77 struct sysfs_dirent *kernfs_create_file_ns_key(struct sysfs_dirent *parent,
78                                                const char *name,
79                                                umode_t mode, loff_t size,
80                                                const struct kernfs_ops *ops,
81                                                void *priv, const void *ns,
82                                                struct lock_class_key *key);
83 struct sysfs_dirent *kernfs_create_link(struct sysfs_dirent *parent,
84                                         const char *name,
85                                         struct sysfs_dirent *target);
86 void kernfs_remove(struct sysfs_dirent *sd);
87 int kernfs_remove_by_name_ns(struct sysfs_dirent *parent, const char *name,
88                              const void *ns);
89 int kernfs_rename_ns(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent,
90                      const char *new_name, const void *new_ns);
91 void kernfs_enable_ns(struct sysfs_dirent *sd);
92 int kernfs_setattr(struct sysfs_dirent *sd, const struct iattr *iattr);
93 void kernfs_notify(struct sysfs_dirent *sd);
94
95 #else   /* CONFIG_SYSFS */
96
97 static inline struct sysfs_dirent *
98 kernfs_create_dir_ns(struct sysfs_dirent *parent, const char *name, void *priv,
99                      const void *ns)
100 { return ERR_PTR(-ENOSYS); }
101
102 static inline struct sysfs_dirent *
103 kernfs_create_file_ns_key(struct sysfs_dirent *parent, const char *name,
104                           umode_t mode, loff_t size,
105                           const struct kernfs_ops *ops, void *priv,
106                           const void *ns, struct lock_class_key *key)
107 { return ERR_PTR(-ENOSYS); }
108
109 static inline struct sysfs_dirent *
110 kernfs_create_link(struct sysfs_dirent *parent, const char *name,
111                    struct sysfs_dirent *target)
112 { return ERR_PTR(-ENOSYS); }
113
114 static inline void kernfs_remove(struct sysfs_dirent *sd) { }
115
116 static inline int kernfs_remove_by_name_ns(struct sysfs_dirent *parent,
117                                            const char *name, const void *ns)
118 { return -ENOSYS; }
119
120 static inline int kernfs_rename_ns(struct sysfs_dirent *sd,
121                                    struct sysfs_dirent *new_parent,
122                                    const char *new_name, const void *new_ns)
123 { return -ENOSYS; }
124
125 static inline void kernfs_enable_ns(struct sysfs_dirent *sd) { }
126
127 static inline int kernfs_setattr(struct sysfs_dirent *sd,
128                                  const struct iattr *iattr)
129 { return -ENOSYS; }
130
131 static inline void kernfs_notify(struct sysfs_dirent *sd) { }
132
133 #endif  /* CONFIG_SYSFS */
134
135 static inline struct sysfs_dirent *
136 kernfs_create_dir(struct sysfs_dirent *parent, const char *name, void *priv)
137 {
138         return kernfs_create_dir_ns(parent, name, priv, NULL);
139 }
140
141 static inline struct sysfs_dirent *
142 kernfs_create_file_ns(struct sysfs_dirent *parent, const char *name,
143                       umode_t mode, loff_t size, const struct kernfs_ops *ops,
144                       void *priv, const void *ns)
145 {
146         struct lock_class_key *key = NULL;
147
148 #ifdef CONFIG_DEBUG_LOCK_ALLOC
149         key = (struct lock_class_key *)&ops->lockdep_key;
150 #endif
151         return kernfs_create_file_ns_key(parent, name, mode, size, ops, priv,
152                                          ns, key);
153 }
154
155 static inline struct sysfs_dirent *
156 kernfs_create_file(struct sysfs_dirent *parent, const char *name, umode_t mode,
157                    loff_t size, const struct kernfs_ops *ops, void *priv)
158 {
159         return kernfs_create_file_ns(parent, name, mode, size, ops, priv, NULL);
160 }
161
162 static inline int kernfs_remove_by_name(struct sysfs_dirent *parent,
163                                         const char *name)
164 {
165         return kernfs_remove_by_name_ns(parent, name, NULL);
166 }
167
168 #endif  /* __LINUX_KERNFS_H */