aboutsummaryrefslogtreecommitdiffstats
path: root/fs/debugfs/file.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-05-21 00:26:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-21 00:26:15 -0400
commit3aa2fc1667acdd9cca816a2bc9529f494bd61b05 (patch)
tree2379f33e47edacbc7a4bdf19607642d9c53caa11 /fs/debugfs/file.c
parent5af2344013454640e0133bb62e8cf2e30190a472 (diff)
parentc6e360a0d9d282e9c8688dcdabdc3669912b66ef (diff)
Merge tag 'driver-core-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core updates from Greg KH: "Here's the "big" driver core update for 4.7-rc1. Mostly just debugfs changes, the long-known and messy races with removing debugfs files should be fixed thanks to the great work of Nicolai Stange. We also have some isa updates in here (the x86 maintainers told me to take it through this tree), a new warning when we run out of dynamic char major numbers, and a few other assorted changes, details in the shortlog. All have been in linux-next for some time with no reported issues" * tag 'driver-core-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (32 commits) Revert "base: dd: don't remove driver_data in -EPROBE_DEFER case" gpio: ws16c48: Utilize the ISA bus driver gpio: 104-idio-16: Utilize the ISA bus driver gpio: 104-idi-48: Utilize the ISA bus driver gpio: 104-dio-48e: Utilize the ISA bus driver watchdog: ebc-c384_wdt: Utilize the ISA bus driver iio: stx104: Utilize the module_isa_driver and max_num_isa_dev macros iio: stx104: Add X86 dependency to STX104 Kconfig option Documentation: Add ISA bus driver documentation isa: Implement the max_num_isa_dev macro isa: Implement the module_isa_driver macro pnp: pnpbios: Add explicit X86_32 dependency to PNPBIOS isa: Decouple X86_32 dependency from the ISA Kconfig option driver-core: use 'dev' argument in dev_dbg_ratelimited stub base: dd: don't remove driver_data in -EPROBE_DEFER case kernfs: Move faulting copy_user operations outside of the mutex devcoredump: add scatterlist support debugfs: unproxify files created through debugfs_create_u32_array() debugfs: unproxify files created through debugfs_create_blob() debugfs: unproxify files created through debugfs_create_bool() ...
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