aboutsummaryrefslogtreecommitdiffstats
path: root/fs/debugfs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/debugfs/file.c')
-rw-r--r--fs/debugfs/file.c436
1 files changed, 370 insertions, 66 deletions
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index d2ba12e23ed9..9c1c9a01b7e5 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -22,6 +22,12 @@
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/atomic.h> 23#include <linux/atomic.h>
24#include <linux/device.h> 24#include <linux/device.h>
25#include <linux/srcu.h>
26#include <asm/poll.h>
27
28#include "internal.h"
29
30struct poll_table_struct;
25 31
26static ssize_t default_read_file(struct file *file, char __user *buf, 32static ssize_t default_read_file(struct file *file, char __user *buf,
27 size_t count, loff_t *ppos) 33 size_t count, loff_t *ppos)
@@ -35,27 +41,293 @@ static ssize_t default_write_file(struct file *file, const char __user *buf,
35 return count; 41 return count;
36} 42}
37 43
38const struct file_operations debugfs_file_operations = { 44const struct file_operations debugfs_noop_file_operations = {
39 .read = default_read_file, 45 .read = default_read_file,
40 .write = default_write_file, 46 .write = default_write_file,
41 .open = simple_open, 47 .open = simple_open,
42 .llseek = noop_llseek, 48 .llseek = noop_llseek,
43}; 49};
44 50
45static struct dentry *debugfs_create_mode(const char *name, umode_t mode, 51/**
46 struct dentry *parent, void *value, 52 * debugfs_use_file_start - mark the beginning of file data access
47 const struct file_operations *fops, 53 * @dentry: the dentry object whose data is being accessed.
48 const struct file_operations *fops_ro, 54 * @srcu_idx: a pointer to some memory to store a SRCU index in.
49 const struct file_operations *fops_wo) 55 *
56 * Up to a matching call to debugfs_use_file_finish(), any
57 * successive call into the file removing functions debugfs_remove()
58 * and debugfs_remove_recursive() will block. Since associated private
59 * file data may only get freed after a successful return of any of
60 * the removal functions, you may safely access it after a successful
61 * call to debugfs_use_file_start() without worrying about
62 * lifetime issues.
63 *
64 * If -%EIO is returned, the file has already been removed and thus,
65 * it is not safe to access any of its data. If, on the other hand,
66 * it is allowed to access the file data, zero is returned.
67 *
68 * Regardless of the return code, any call to
69 * debugfs_use_file_start() must be followed by a matching call
70 * to debugfs_use_file_finish().
71 */
72int debugfs_use_file_start(const struct dentry *dentry, int *srcu_idx)
73 __acquires(&debugfs_srcu)
74{
75 *srcu_idx = srcu_read_lock(&debugfs_srcu);
76 barrier();
77 if (d_unlinked(dentry))
78 return -EIO;
79 return 0;
80}
81EXPORT_SYMBOL_GPL(debugfs_use_file_start);
82
83/**
84 * debugfs_use_file_finish - mark the end of file data access
85 * @srcu_idx: the SRCU index "created" by a former call to
86 * debugfs_use_file_start().
87 *
88 * Allow any ongoing concurrent call into debugfs_remove() or
89 * debugfs_remove_recursive() blocked by a former call to
90 * debugfs_use_file_start() to proceed and return to its caller.
91 */
92void debugfs_use_file_finish(int srcu_idx) __releases(&debugfs_srcu)
93{
94 srcu_read_unlock(&debugfs_srcu, srcu_idx);
95}
96EXPORT_SYMBOL_GPL(debugfs_use_file_finish);
97
98#define F_DENTRY(filp) ((filp)->f_path.dentry)
99
100#define REAL_FOPS_DEREF(dentry) \
101 ((const struct file_operations *)(dentry)->d_fsdata)
102
103static int open_proxy_open(struct inode *inode, struct file *filp)
104{
105 const struct dentry *dentry = F_DENTRY(filp);
106 const struct file_operations *real_fops = NULL;
107 int srcu_idx, r;
108
109 r = debugfs_use_file_start(dentry, &srcu_idx);
110 if (r) {
111 r = -ENOENT;
112 goto out;
113 }
114
115 real_fops = REAL_FOPS_DEREF(dentry);
116 real_fops = fops_get(real_fops);
117 if (!real_fops) {
118 /* Huh? Module did not clean up after itself at exit? */
119 WARN(1, "debugfs file owner did not clean up at exit: %pd",
120 dentry);
121 r = -ENXIO;
122 goto out;
123 }
124 replace_fops(filp, real_fops);
125
126 if (real_fops->open)
127 r = real_fops->open(inode, filp);
128
129out:
130 fops_put(real_fops);
131 debugfs_use_file_finish(srcu_idx);
132 return r;
133}
134
135const struct file_operations debugfs_open_proxy_file_operations = {
136 .open = open_proxy_open,
137};
138
139#define PROTO(args...) args
140#define ARGS(args...) args
141
142#define FULL_PROXY_FUNC(name, ret_type, filp, proto, args) \
143static ret_type full_proxy_ ## name(proto) \
144{ \
145 const struct dentry *dentry = F_DENTRY(filp); \
146 const struct file_operations *real_fops = \
147 REAL_FOPS_DEREF(dentry); \
148 int srcu_idx; \
149 ret_type r; \
150 \
151 r = debugfs_use_file_start(dentry, &srcu_idx); \
152 if (likely(!r)) \
153 r = real_fops->name(args); \
154 debugfs_use_file_finish(srcu_idx); \
155 return r; \
156}
157
158FULL_PROXY_FUNC(llseek, loff_t, filp,
159 PROTO(struct file *filp, loff_t offset, int whence),
160 ARGS(filp, offset, whence));
161
162FULL_PROXY_FUNC(read, ssize_t, filp,
163 PROTO(struct file *filp, char __user *buf, size_t size,
164 loff_t *ppos),
165 ARGS(filp, buf, size, ppos));
166
167FULL_PROXY_FUNC(write, ssize_t, filp,
168 PROTO(struct file *filp, const char __user *buf, size_t size,
169 loff_t *ppos),
170 ARGS(filp, buf, size, ppos));
171
172FULL_PROXY_FUNC(unlocked_ioctl, long, filp,
173 PROTO(struct file *filp, unsigned int cmd, unsigned long arg),
174 ARGS(filp, cmd, arg));
175
176static unsigned int full_proxy_poll(struct file *filp,
177 struct poll_table_struct *wait)
178{
179 const struct dentry *dentry = F_DENTRY(filp);
180 const struct file_operations *real_fops = REAL_FOPS_DEREF(dentry);
181 int srcu_idx;
182 unsigned int r = 0;
183
184 if (debugfs_use_file_start(dentry, &srcu_idx)) {
185 debugfs_use_file_finish(srcu_idx);
186 return POLLHUP;
187 }
188
189 r = real_fops->poll(filp, wait);
190 debugfs_use_file_finish(srcu_idx);
191 return r;
192}
193
194static int full_proxy_release(struct inode *inode, struct file *filp)
195{
196 const struct dentry *dentry = F_DENTRY(filp);
197 const struct file_operations *real_fops = REAL_FOPS_DEREF(dentry);
198 const struct file_operations *proxy_fops = filp->f_op;
199 int r = 0;
200
201 /*
202 * We must not protect this against removal races here: the
203 * original releaser should be called unconditionally in order
204 * not to leak any resources. Releasers must not assume that
205 * ->i_private is still being meaningful here.
206 */
207 if (real_fops->release)
208 r = real_fops->release(inode, filp);
209
210 replace_fops(filp, d_inode(dentry)->i_fop);
211 kfree((void *)proxy_fops);
212 fops_put(real_fops);
213 return 0;
214}
215
216static void __full_proxy_fops_init(struct file_operations *proxy_fops,
217 const struct file_operations *real_fops)
218{
219 proxy_fops->release = full_proxy_release;
220 if (real_fops->llseek)
221 proxy_fops->llseek = full_proxy_llseek;
222 if (real_fops->read)
223 proxy_fops->read = full_proxy_read;
224 if (real_fops->write)
225 proxy_fops->write = full_proxy_write;
226 if (real_fops->poll)
227 proxy_fops->poll = full_proxy_poll;
228 if (real_fops->unlocked_ioctl)
229 proxy_fops->unlocked_ioctl = full_proxy_unlocked_ioctl;
230}
231
232static int full_proxy_open(struct inode *inode, struct file *filp)
233{
234 const struct dentry *dentry = F_DENTRY(filp);
235 const struct file_operations *real_fops = NULL;
236 struct file_operations *proxy_fops = NULL;
237 int srcu_idx, r;
238
239 r = debugfs_use_file_start(dentry, &srcu_idx);
240 if (r) {
241 r = -ENOENT;
242 goto out;
243 }
244
245 real_fops = REAL_FOPS_DEREF(dentry);
246 real_fops = fops_get(real_fops);
247 if (!real_fops) {
248 /* Huh? Module did not cleanup after itself at exit? */
249 WARN(1, "debugfs file owner did not clean up at exit: %pd",
250 dentry);
251 r = -ENXIO;
252 goto out;
253 }
254
255 proxy_fops = kzalloc(sizeof(*proxy_fops), GFP_KERNEL);
256 if (!proxy_fops) {
257 r = -ENOMEM;
258 goto free_proxy;
259 }
260 __full_proxy_fops_init(proxy_fops, real_fops);
261 replace_fops(filp, proxy_fops);
262
263 if (real_fops->open) {
264 r = real_fops->open(inode, filp);
265
266 if (filp->f_op != proxy_fops) {
267 /* No protection against file removal anymore. */
268 WARN(1, "debugfs file owner replaced proxy fops: %pd",
269 dentry);
270 goto free_proxy;
271 }
272 }
273
274 goto out;
275free_proxy:
276 kfree(proxy_fops);
277 fops_put(real_fops);
278out:
279 debugfs_use_file_finish(srcu_idx);
280 return r;
281}
282
283const struct file_operations debugfs_full_proxy_file_operations = {
284 .open = full_proxy_open,
285};
286
287ssize_t debugfs_attr_read(struct file *file, char __user *buf,
288 size_t len, loff_t *ppos)
289{
290 ssize_t ret;
291 int srcu_idx;
292
293 ret = debugfs_use_file_start(F_DENTRY(file), &srcu_idx);
294 if (likely(!ret))
295 ret = simple_attr_read(file, buf, len, ppos);
296 debugfs_use_file_finish(srcu_idx);
297 return ret;
298}
299EXPORT_SYMBOL_GPL(debugfs_attr_read);
300
301ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
302 size_t len, loff_t *ppos)
303{
304 ssize_t ret;
305 int srcu_idx;
306
307 ret = debugfs_use_file_start(F_DENTRY(file), &srcu_idx);
308 if (likely(!ret))
309 ret = simple_attr_write(file, buf, len, ppos);
310 debugfs_use_file_finish(srcu_idx);
311 return ret;
312}
313EXPORT_SYMBOL_GPL(debugfs_attr_write);
314
315static struct dentry *debugfs_create_mode_unsafe(const char *name, umode_t mode,
316 struct dentry *parent, void *value,
317 const struct file_operations *fops,
318 const struct file_operations *fops_ro,
319 const struct file_operations *fops_wo)
50{ 320{
51 /* if there are no write bits set, make read only */ 321 /* if there are no write bits set, make read only */
52 if (!(mode & S_IWUGO)) 322 if (!(mode & S_IWUGO))
53 return debugfs_create_file(name, mode, parent, value, fops_ro); 323 return debugfs_create_file_unsafe(name, mode, parent, value,
324 fops_ro);
54 /* if there are no read bits set, make write only */ 325 /* if there are no read bits set, make write only */
55 if (!(mode & S_IRUGO)) 326 if (!(mode & S_IRUGO))
56 return debugfs_create_file(name, mode, parent, value, fops_wo); 327 return debugfs_create_file_unsafe(name, mode, parent, value,
328 fops_wo);
57 329
58 return debugfs_create_file(name, mode, parent, value, fops); 330 return debugfs_create_file_unsafe(name, mode, parent, value, fops);
59} 331}
60 332
61static int debugfs_u8_set(void *data, u64 val) 333static int debugfs_u8_set(void *data, u64 val)
@@ -68,9 +340,9 @@ static int debugfs_u8_get(void *data, u64 *val)
68 *val = *(u8 *)data; 340 *val = *(u8 *)data;
69 return 0; 341 return 0;
70} 342}
71DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n"); 343DEFINE_DEBUGFS_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n");
72DEFINE_SIMPLE_ATTRIBUTE(fops_u8_ro, debugfs_u8_get, NULL, "%llu\n"); 344DEFINE_DEBUGFS_ATTRIBUTE(fops_u8_ro, debugfs_u8_get, NULL, "%llu\n");
73DEFINE_SIMPLE_ATTRIBUTE(fops_u8_wo, NULL, debugfs_u8_set, "%llu\n"); 345DEFINE_DEBUGFS_ATTRIBUTE(fops_u8_wo, NULL, debugfs_u8_set, "%llu\n");
74 346
75/** 347/**
76 * debugfs_create_u8 - create a debugfs file that is used to read and write an unsigned 8-bit value 348 * debugfs_create_u8 - create a debugfs file that is used to read and write an unsigned 8-bit value
@@ -99,7 +371,7 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_u8_wo, NULL, debugfs_u8_set, "%llu\n");
99struct dentry *debugfs_create_u8(const char *name, umode_t mode, 371struct dentry *debugfs_create_u8(const char *name, umode_t mode,
100 struct dentry *parent, u8 *value) 372 struct dentry *parent, u8 *value)
101{ 373{
102 return debugfs_create_mode(name, mode, parent, value, &fops_u8, 374 return debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u8,
103 &fops_u8_ro, &fops_u8_wo); 375 &fops_u8_ro, &fops_u8_wo);
104} 376}
105EXPORT_SYMBOL_GPL(debugfs_create_u8); 377EXPORT_SYMBOL_GPL(debugfs_create_u8);
@@ -114,9 +386,9 @@ static int debugfs_u16_get(void *data, u64 *val)
114 *val = *(u16 *)data; 386 *val = *(u16 *)data;
115 return 0; 387 return 0;
116} 388}
117DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n"); 389DEFINE_DEBUGFS_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n");
118DEFINE_SIMPLE_ATTRIBUTE(fops_u16_ro, debugfs_u16_get, NULL, "%llu\n"); 390DEFINE_DEBUGFS_ATTRIBUTE(fops_u16_ro, debugfs_u16_get, NULL, "%llu\n");
119DEFINE_SIMPLE_ATTRIBUTE(fops_u16_wo, NULL, debugfs_u16_set, "%llu\n"); 391DEFINE_DEBUGFS_ATTRIBUTE(fops_u16_wo, NULL, debugfs_u16_set, "%llu\n");
120 392
121/** 393/**
122 * debugfs_create_u16 - create a debugfs file that is used to read and write an unsigned 16-bit value 394 * debugfs_create_u16 - create a debugfs file that is used to read and write an unsigned 16-bit value
@@ -145,7 +417,7 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_u16_wo, NULL, debugfs_u16_set, "%llu\n");
145struct dentry *debugfs_create_u16(const char *name, umode_t mode, 417struct dentry *debugfs_create_u16(const char *name, umode_t mode,
146 struct dentry *parent, u16 *value) 418 struct dentry *parent, u16 *value)
147{ 419{
148 return debugfs_create_mode(name, mode, parent, value, &fops_u16, 420 return debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u16,
149 &fops_u16_ro, &fops_u16_wo); 421 &fops_u16_ro, &fops_u16_wo);
150} 422}
151EXPORT_SYMBOL_GPL(debugfs_create_u16); 423EXPORT_SYMBOL_GPL(debugfs_create_u16);
@@ -160,9 +432,9 @@ static int debugfs_u32_get(void *data, u64 *val)
160 *val = *(u32 *)data; 432 *val = *(u32 *)data;
161 return 0; 433 return 0;
162} 434}
163DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n"); 435DEFINE_DEBUGFS_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n");
164DEFINE_SIMPLE_ATTRIBUTE(fops_u32_ro, debugfs_u32_get, NULL, "%llu\n"); 436DEFINE_DEBUGFS_ATTRIBUTE(fops_u32_ro, debugfs_u32_get, NULL, "%llu\n");
165DEFINE_SIMPLE_ATTRIBUTE(fops_u32_wo, NULL, debugfs_u32_set, "%llu\n"); 437DEFINE_DEBUGFS_ATTRIBUTE(fops_u32_wo, NULL, debugfs_u32_set, "%llu\n");
166 438
167/** 439/**
168 * debugfs_create_u32 - create a debugfs file that is used to read and write an unsigned 32-bit value 440 * debugfs_create_u32 - create a debugfs file that is used to read and write an unsigned 32-bit value
@@ -191,7 +463,7 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_u32_wo, NULL, debugfs_u32_set, "%llu\n");
191struct dentry *debugfs_create_u32(const char *name, umode_t mode, 463struct dentry *debugfs_create_u32(const char *name, umode_t mode,
192 struct dentry *parent, u32 *value) 464 struct dentry *parent, u32 *value)
193{ 465{
194 return debugfs_create_mode(name, mode, parent, value, &fops_u32, 466 return debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u32,
195 &fops_u32_ro, &fops_u32_wo); 467 &fops_u32_ro, &fops_u32_wo);
196} 468}
197EXPORT_SYMBOL_GPL(debugfs_create_u32); 469EXPORT_SYMBOL_GPL(debugfs_create_u32);
@@ -207,9 +479,9 @@ static int debugfs_u64_get(void *data, u64 *val)
207 *val = *(u64 *)data; 479 *val = *(u64 *)data;
208 return 0; 480 return 0;
209} 481}
210DEFINE_SIMPLE_ATTRIBUTE(fops_u64, debugfs_u64_get, debugfs_u64_set, "%llu\n"); 482DEFINE_DEBUGFS_ATTRIBUTE(fops_u64, debugfs_u64_get, debugfs_u64_set, "%llu\n");
211DEFINE_SIMPLE_ATTRIBUTE(fops_u64_ro, debugfs_u64_get, NULL, "%llu\n"); 483DEFINE_DEBUGFS_ATTRIBUTE(fops_u64_ro, debugfs_u64_get, NULL, "%llu\n");
212DEFINE_SIMPLE_ATTRIBUTE(fops_u64_wo, NULL, debugfs_u64_set, "%llu\n"); 484DEFINE_DEBUGFS_ATTRIBUTE(fops_u64_wo, NULL, debugfs_u64_set, "%llu\n");
213 485
214/** 486/**
215 * debugfs_create_u64 - create a debugfs file that is used to read and write an unsigned 64-bit value 487 * debugfs_create_u64 - create a debugfs file that is used to read and write an unsigned 64-bit value
@@ -238,7 +510,7 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_u64_wo, NULL, debugfs_u64_set, "%llu\n");
238struct dentry *debugfs_create_u64(const char *name, umode_t mode, 510struct dentry *debugfs_create_u64(const char *name, umode_t mode,
239 struct dentry *parent, u64 *value) 511 struct dentry *parent, u64 *value)
240{ 512{
241 return debugfs_create_mode(name, mode, parent, value, &fops_u64, 513 return debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u64,
242 &fops_u64_ro, &fops_u64_wo); 514 &fops_u64_ro, &fops_u64_wo);
243} 515}
244EXPORT_SYMBOL_GPL(debugfs_create_u64); 516EXPORT_SYMBOL_GPL(debugfs_create_u64);
@@ -254,9 +526,10 @@ static int debugfs_ulong_get(void *data, u64 *val)
254 *val = *(unsigned long *)data; 526 *val = *(unsigned long *)data;
255 return 0; 527 return 0;
256} 528}
257DEFINE_SIMPLE_ATTRIBUTE(fops_ulong, debugfs_ulong_get, debugfs_ulong_set, "%llu\n"); 529DEFINE_DEBUGFS_ATTRIBUTE(fops_ulong, debugfs_ulong_get, debugfs_ulong_set,
258DEFINE_SIMPLE_ATTRIBUTE(fops_ulong_ro, debugfs_ulong_get, NULL, "%llu\n"); 530 "%llu\n");
259DEFINE_SIMPLE_ATTRIBUTE(fops_ulong_wo, NULL, debugfs_ulong_set, "%llu\n"); 531DEFINE_DEBUGFS_ATTRIBUTE(fops_ulong_ro, debugfs_ulong_get, NULL, "%llu\n");
532DEFINE_DEBUGFS_ATTRIBUTE(fops_ulong_wo, NULL, debugfs_ulong_set, "%llu\n");
260 533
261/** 534/**
262 * debugfs_create_ulong - create a debugfs file that is used to read and write 535 * debugfs_create_ulong - create a debugfs file that is used to read and write
@@ -286,26 +559,30 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_ulong_wo, NULL, debugfs_ulong_set, "%llu\n");
286struct dentry *debugfs_create_ulong(const char *name, umode_t mode, 559struct dentry *debugfs_create_ulong(const char *name, umode_t mode,
287 struct dentry *parent, unsigned long *value) 560 struct dentry *parent, unsigned long *value)
288{ 561{
289 return debugfs_create_mode(name, mode, parent, value, &fops_ulong, 562 return debugfs_create_mode_unsafe(name, mode, parent, value,
290 &fops_ulong_ro, &fops_ulong_wo); 563 &fops_ulong, &fops_ulong_ro,
564 &fops_ulong_wo);
291} 565}
292EXPORT_SYMBOL_GPL(debugfs_create_ulong); 566EXPORT_SYMBOL_GPL(debugfs_create_ulong);
293 567
294DEFINE_SIMPLE_ATTRIBUTE(fops_x8, debugfs_u8_get, debugfs_u8_set, "0x%02llx\n"); 568DEFINE_DEBUGFS_ATTRIBUTE(fops_x8, debugfs_u8_get, debugfs_u8_set, "0x%02llx\n");
295DEFINE_SIMPLE_ATTRIBUTE(fops_x8_ro, debugfs_u8_get, NULL, "0x%02llx\n"); 569DEFINE_DEBUGFS_ATTRIBUTE(fops_x8_ro, debugfs_u8_get, NULL, "0x%02llx\n");
296DEFINE_SIMPLE_ATTRIBUTE(fops_x8_wo, NULL, debugfs_u8_set, "0x%02llx\n"); 570DEFINE_DEBUGFS_ATTRIBUTE(fops_x8_wo, NULL, debugfs_u8_set, "0x%02llx\n");
297 571
298DEFINE_SIMPLE_ATTRIBUTE(fops_x16, debugfs_u16_get, debugfs_u16_set, "0x%04llx\n"); 572DEFINE_DEBUGFS_ATTRIBUTE(fops_x16, debugfs_u16_get, debugfs_u16_set,
299DEFINE_SIMPLE_ATTRIBUTE(fops_x16_ro, debugfs_u16_get, NULL, "0x%04llx\n"); 573 "0x%04llx\n");
300DEFINE_SIMPLE_ATTRIBUTE(fops_x16_wo, NULL, debugfs_u16_set, "0x%04llx\n"); 574DEFINE_DEBUGFS_ATTRIBUTE(fops_x16_ro, debugfs_u16_get, NULL, "0x%04llx\n");
575DEFINE_DEBUGFS_ATTRIBUTE(fops_x16_wo, NULL, debugfs_u16_set, "0x%04llx\n");
301 576
302DEFINE_SIMPLE_ATTRIBUTE(fops_x32, debugfs_u32_get, debugfs_u32_set, "0x%08llx\n"); 577DEFINE_DEBUGFS_ATTRIBUTE(fops_x32, debugfs_u32_get, debugfs_u32_set,
303DEFINE_SIMPLE_ATTRIBUTE(fops_x32_ro, debugfs_u32_get, NULL, "0x%08llx\n"); 578 "0x%08llx\n");
304DEFINE_SIMPLE_ATTRIBUTE(fops_x32_wo, NULL, debugfs_u32_set, "0x%08llx\n"); 579DEFINE_DEBUGFS_ATTRIBUTE(fops_x32_ro, debugfs_u32_get, NULL, "0x%08llx\n");
580DEFINE_DEBUGFS_ATTRIBUTE(fops_x32_wo, NULL, debugfs_u32_set, "0x%08llx\n");
305 581
306DEFINE_SIMPLE_ATTRIBUTE(fops_x64, debugfs_u64_get, debugfs_u64_set, "0x%016llx\n"); 582DEFINE_DEBUGFS_ATTRIBUTE(fops_x64, debugfs_u64_get, debugfs_u64_set,
307DEFINE_SIMPLE_ATTRIBUTE(fops_x64_ro, debugfs_u64_get, NULL, "0x%016llx\n"); 583 "0x%016llx\n");
308DEFINE_SIMPLE_ATTRIBUTE(fops_x64_wo, NULL, debugfs_u64_set, "0x%016llx\n"); 584DEFINE_DEBUGFS_ATTRIBUTE(fops_x64_ro, debugfs_u64_get, NULL, "0x%016llx\n");
585DEFINE_DEBUGFS_ATTRIBUTE(fops_x64_wo, NULL, debugfs_u64_set, "0x%016llx\n");
309 586
310/* 587/*
311 * debugfs_create_x{8,16,32,64} - create a debugfs file that is used to read and write an unsigned {8,16,32,64}-bit value 588 * debugfs_create_x{8,16,32,64} - create a debugfs file that is used to read and write an unsigned {8,16,32,64}-bit value
@@ -328,7 +605,7 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_x64_wo, NULL, debugfs_u64_set, "0x%016llx\n");
328struct dentry *debugfs_create_x8(const char *name, umode_t mode, 605struct dentry *debugfs_create_x8(const char *name, umode_t mode,
329 struct dentry *parent, u8 *value) 606 struct dentry *parent, u8 *value)
330{ 607{
331 return debugfs_create_mode(name, mode, parent, value, &fops_x8, 608 return debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x8,
332 &fops_x8_ro, &fops_x8_wo); 609 &fops_x8_ro, &fops_x8_wo);
333} 610}
334EXPORT_SYMBOL_GPL(debugfs_create_x8); 611EXPORT_SYMBOL_GPL(debugfs_create_x8);
@@ -346,7 +623,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_x8);
346struct dentry *debugfs_create_x16(const char *name, umode_t mode, 623struct dentry *debugfs_create_x16(const char *name, umode_t mode,
347 struct dentry *parent, u16 *value) 624 struct dentry *parent, u16 *value)
348{ 625{
349 return debugfs_create_mode(name, mode, parent, value, &fops_x16, 626 return debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x16,
350 &fops_x16_ro, &fops_x16_wo); 627 &fops_x16_ro, &fops_x16_wo);
351} 628}
352EXPORT_SYMBOL_GPL(debugfs_create_x16); 629EXPORT_SYMBOL_GPL(debugfs_create_x16);
@@ -364,7 +641,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_x16);
364struct dentry *debugfs_create_x32(const char *name, umode_t mode, 641struct dentry *debugfs_create_x32(const char *name, umode_t mode,
365 struct dentry *parent, u32 *value) 642 struct dentry *parent, u32 *value)
366{ 643{
367 return debugfs_create_mode(name, mode, parent, value, &fops_x32, 644 return debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x32,
368 &fops_x32_ro, &fops_x32_wo); 645 &fops_x32_ro, &fops_x32_wo);
369} 646}
370EXPORT_SYMBOL_GPL(debugfs_create_x32); 647EXPORT_SYMBOL_GPL(debugfs_create_x32);
@@ -382,7 +659,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_x32);
382struct dentry *debugfs_create_x64(const char *name, umode_t mode, 659struct dentry *debugfs_create_x64(const char *name, umode_t mode,
383 struct dentry *parent, u64 *value) 660 struct dentry *parent, u64 *value)
384{ 661{
385 return debugfs_create_mode(name, mode, parent, value, &fops_x64, 662 return debugfs_create_mode_unsafe(name, mode, parent, value, &fops_x64,
386 &fops_x64_ro, &fops_x64_wo); 663 &fops_x64_ro, &fops_x64_wo);
387} 664}
388EXPORT_SYMBOL_GPL(debugfs_create_x64); 665EXPORT_SYMBOL_GPL(debugfs_create_x64);
@@ -398,10 +675,10 @@ static int debugfs_size_t_get(void *data, u64 *val)
398 *val = *(size_t *)data; 675 *val = *(size_t *)data;
399 return 0; 676 return 0;
400} 677}
401DEFINE_SIMPLE_ATTRIBUTE(fops_size_t, debugfs_size_t_get, debugfs_size_t_set, 678DEFINE_DEBUGFS_ATTRIBUTE(fops_size_t, debugfs_size_t_get, debugfs_size_t_set,
402 "%llu\n"); /* %llu and %zu are more or less the same */ 679 "%llu\n"); /* %llu and %zu are more or less the same */
403DEFINE_SIMPLE_ATTRIBUTE(fops_size_t_ro, debugfs_size_t_get, NULL, "%llu\n"); 680DEFINE_DEBUGFS_ATTRIBUTE(fops_size_t_ro, debugfs_size_t_get, NULL, "%llu\n");
404DEFINE_SIMPLE_ATTRIBUTE(fops_size_t_wo, NULL, debugfs_size_t_set, "%llu\n"); 681DEFINE_DEBUGFS_ATTRIBUTE(fops_size_t_wo, NULL, debugfs_size_t_set, "%llu\n");
405 682
406/** 683/**
407 * debugfs_create_size_t - create a debugfs file that is used to read and write an size_t value 684 * debugfs_create_size_t - create a debugfs file that is used to read and write an size_t value
@@ -416,8 +693,9 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_size_t_wo, NULL, debugfs_size_t_set, "%llu\n");
416struct dentry *debugfs_create_size_t(const char *name, umode_t mode, 693struct dentry *debugfs_create_size_t(const char *name, umode_t mode,
417 struct dentry *parent, size_t *value) 694 struct dentry *parent, size_t *value)
418{ 695{
419 return debugfs_create_mode(name, mode, parent, value, &fops_size_t, 696 return debugfs_create_mode_unsafe(name, mode, parent, value,
420 &fops_size_t_ro, &fops_size_t_wo); 697 &fops_size_t, &fops_size_t_ro,
698 &fops_size_t_wo);
421} 699}
422EXPORT_SYMBOL_GPL(debugfs_create_size_t); 700EXPORT_SYMBOL_GPL(debugfs_create_size_t);
423 701
@@ -431,10 +709,12 @@ static int debugfs_atomic_t_get(void *data, u64 *val)
431 *val = atomic_read((atomic_t *)data); 709 *val = atomic_read((atomic_t *)data);
432 return 0; 710 return 0;
433} 711}
434DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t, debugfs_atomic_t_get, 712DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t, debugfs_atomic_t_get,
435 debugfs_atomic_t_set, "%lld\n"); 713 debugfs_atomic_t_set, "%lld\n");
436DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t_ro, debugfs_atomic_t_get, NULL, "%lld\n"); 714DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_ro, debugfs_atomic_t_get, NULL,
437DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t_wo, NULL, debugfs_atomic_t_set, "%lld\n"); 715 "%lld\n");
716DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_wo, NULL, debugfs_atomic_t_set,
717 "%lld\n");
438 718
439/** 719/**
440 * debugfs_create_atomic_t - create a debugfs file that is used to read and 720 * debugfs_create_atomic_t - create a debugfs file that is used to read and
@@ -450,8 +730,9 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t_wo, NULL, debugfs_atomic_t_set, "%lld\n");
450struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode, 730struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode,
451 struct dentry *parent, atomic_t *value) 731 struct dentry *parent, atomic_t *value)
452{ 732{
453 return debugfs_create_mode(name, mode, parent, value, &fops_atomic_t, 733 return debugfs_create_mode_unsafe(name, mode, parent, value,
454 &fops_atomic_t_ro, &fops_atomic_t_wo); 734 &fops_atomic_t, &fops_atomic_t_ro,
735 &fops_atomic_t_wo);
455} 736}
456EXPORT_SYMBOL_GPL(debugfs_create_atomic_t); 737EXPORT_SYMBOL_GPL(debugfs_create_atomic_t);
457 738
@@ -459,9 +740,17 @@ ssize_t debugfs_read_file_bool(struct file *file, char __user *user_buf,
459 size_t count, loff_t *ppos) 740 size_t count, loff_t *ppos)
460{ 741{
461 char buf[3]; 742 char buf[3];
462 bool *val = file->private_data; 743 bool val;
744 int r, srcu_idx;
463 745
464 if (*val) 746 r = debugfs_use_file_start(F_DENTRY(file), &srcu_idx);
747 if (likely(!r))
748 val = *(bool *)file->private_data;
749 debugfs_use_file_finish(srcu_idx);
750 if (r)
751 return r;
752
753 if (val)
465 buf[0] = 'Y'; 754 buf[0] = 'Y';
466 else 755 else
467 buf[0] = 'N'; 756 buf[0] = 'N';
@@ -477,6 +766,7 @@ ssize_t debugfs_write_file_bool(struct file *file, const char __user *user_buf,
477 char buf[32]; 766 char buf[32];
478 size_t buf_size; 767 size_t buf_size;
479 bool bv; 768 bool bv;
769 int r, srcu_idx;
480 bool *val = file->private_data; 770 bool *val = file->private_data;
481 771
482 buf_size = min(count, (sizeof(buf)-1)); 772 buf_size = min(count, (sizeof(buf)-1));
@@ -484,8 +774,14 @@ ssize_t debugfs_write_file_bool(struct file *file, const char __user *user_buf,
484 return -EFAULT; 774 return -EFAULT;
485 775
486 buf[buf_size] = '\0'; 776 buf[buf_size] = '\0';
487 if (strtobool(buf, &bv) == 0) 777 if (strtobool(buf, &bv) == 0) {
488 *val = bv; 778 r = debugfs_use_file_start(F_DENTRY(file), &srcu_idx);
779 if (likely(!r))
780 *val = bv;
781 debugfs_use_file_finish(srcu_idx);
782 if (r)
783 return r;
784 }
489 785
490 return count; 786 return count;
491} 787}
@@ -537,7 +833,7 @@ static const struct file_operations fops_bool_wo = {
537struct dentry *debugfs_create_bool(const char *name, umode_t mode, 833struct dentry *debugfs_create_bool(const char *name, umode_t mode,
538 struct dentry *parent, bool *value) 834 struct dentry *parent, bool *value)
539{ 835{
540 return debugfs_create_mode(name, mode, parent, value, &fops_bool, 836 return debugfs_create_mode_unsafe(name, mode, parent, value, &fops_bool,
541 &fops_bool_ro, &fops_bool_wo); 837 &fops_bool_ro, &fops_bool_wo);
542} 838}
543EXPORT_SYMBOL_GPL(debugfs_create_bool); 839EXPORT_SYMBOL_GPL(debugfs_create_bool);
@@ -546,8 +842,15 @@ static ssize_t read_file_blob(struct file *file, char __user *user_buf,
546 size_t count, loff_t *ppos) 842 size_t count, loff_t *ppos)
547{ 843{
548 struct debugfs_blob_wrapper *blob = file->private_data; 844 struct debugfs_blob_wrapper *blob = file->private_data;
549 return simple_read_from_buffer(user_buf, count, ppos, blob->data, 845 ssize_t r;
550 blob->size); 846 int srcu_idx;
847
848 r = debugfs_use_file_start(F_DENTRY(file), &srcu_idx);
849 if (likely(!r))
850 r = simple_read_from_buffer(user_buf, count, ppos, blob->data,
851 blob->size);
852 debugfs_use_file_finish(srcu_idx);
853 return r;
551} 854}
552 855
553static const struct file_operations fops_blob = { 856static const struct file_operations fops_blob = {
@@ -584,7 +887,7 @@ struct dentry *debugfs_create_blob(const char *name, umode_t mode,
584 struct dentry *parent, 887 struct dentry *parent,
585 struct debugfs_blob_wrapper *blob) 888 struct debugfs_blob_wrapper *blob)
586{ 889{
587 return debugfs_create_file(name, mode, parent, blob, &fops_blob); 890 return debugfs_create_file_unsafe(name, mode, parent, blob, &fops_blob);
588} 891}
589EXPORT_SYMBOL_GPL(debugfs_create_blob); 892EXPORT_SYMBOL_GPL(debugfs_create_blob);
590 893
@@ -689,7 +992,8 @@ struct dentry *debugfs_create_u32_array(const char *name, umode_t mode,
689 data->array = array; 992 data->array = array;
690 data->elements = elements; 993 data->elements = elements;
691 994
692 return debugfs_create_file(name, mode, parent, data, &u32_array_fops); 995 return debugfs_create_file_unsafe(name, mode, parent, data,
996 &u32_array_fops);
693} 997}
694EXPORT_SYMBOL_GPL(debugfs_create_u32_array); 998EXPORT_SYMBOL_GPL(debugfs_create_u32_array);
695 999