aboutsummaryrefslogtreecommitdiffstats
path: root/fs/debugfs/inode.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/inode.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/inode.c')
-rw-r--r--fs/debugfs/inode.c108
1 files changed, 88 insertions, 20 deletions
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 8580831ed237..4bc1f68243c1 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -27,9 +27,14 @@
27#include <linux/parser.h> 27#include <linux/parser.h>
28#include <linux/magic.h> 28#include <linux/magic.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/srcu.h>
31
32#include "internal.h"
30 33
31#define DEBUGFS_DEFAULT_MODE 0700 34#define DEBUGFS_DEFAULT_MODE 0700
32 35
36DEFINE_SRCU(debugfs_srcu);
37
33static struct vfsmount *debugfs_mount; 38static struct vfsmount *debugfs_mount;
34static int debugfs_mount_count; 39static int debugfs_mount_count;
35static bool debugfs_registered; 40static bool debugfs_registered;
@@ -39,7 +44,8 @@ static struct inode *debugfs_get_inode(struct super_block *sb)
39 struct inode *inode = new_inode(sb); 44 struct inode *inode = new_inode(sb);
40 if (inode) { 45 if (inode) {
41 inode->i_ino = get_next_ino(); 46 inode->i_ino = get_next_ino();
42 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 47 inode->i_atime = inode->i_mtime =
48 inode->i_ctime = current_fs_time(sb);
43 } 49 }
44 return inode; 50 return inode;
45} 51}
@@ -294,6 +300,37 @@ static struct dentry *end_creating(struct dentry *dentry)
294 return dentry; 300 return dentry;
295} 301}
296 302
303static struct dentry *__debugfs_create_file(const char *name, umode_t mode,
304 struct dentry *parent, void *data,
305 const struct file_operations *proxy_fops,
306 const struct file_operations *real_fops)
307{
308 struct dentry *dentry;
309 struct inode *inode;
310
311 if (!(mode & S_IFMT))
312 mode |= S_IFREG;
313 BUG_ON(!S_ISREG(mode));
314 dentry = start_creating(name, parent);
315
316 if (IS_ERR(dentry))
317 return NULL;
318
319 inode = debugfs_get_inode(dentry->d_sb);
320 if (unlikely(!inode))
321 return failed_creating(dentry);
322
323 inode->i_mode = mode;
324 inode->i_private = data;
325
326 inode->i_fop = proxy_fops;
327 dentry->d_fsdata = (void *)real_fops;
328
329 d_instantiate(dentry, inode);
330 fsnotify_create(d_inode(dentry->d_parent), dentry);
331 return end_creating(dentry);
332}
333
297/** 334/**
298 * debugfs_create_file - create a file in the debugfs filesystem 335 * debugfs_create_file - create a file in the debugfs filesystem
299 * @name: a pointer to a string containing the name of the file to create. 336 * @name: a pointer to a string containing the name of the file to create.
@@ -324,29 +361,52 @@ struct dentry *debugfs_create_file(const char *name, umode_t mode,
324 struct dentry *parent, void *data, 361 struct dentry *parent, void *data,
325 const struct file_operations *fops) 362 const struct file_operations *fops)
326{ 363{
327 struct dentry *dentry;
328 struct inode *inode;
329 364
330 if (!(mode & S_IFMT)) 365 return __debugfs_create_file(name, mode, parent, data,
331 mode |= S_IFREG; 366 fops ? &debugfs_full_proxy_file_operations :
332 BUG_ON(!S_ISREG(mode)); 367 &debugfs_noop_file_operations,
333 dentry = start_creating(name, parent); 368 fops);
334 369}
335 if (IS_ERR(dentry)) 370EXPORT_SYMBOL_GPL(debugfs_create_file);
336 return NULL;
337 371
338 inode = debugfs_get_inode(dentry->d_sb); 372/**
339 if (unlikely(!inode)) 373 * debugfs_create_file_unsafe - create a file in the debugfs filesystem
340 return failed_creating(dentry); 374 * @name: a pointer to a string containing the name of the file to create.
375 * @mode: the permission that the file should have.
376 * @parent: a pointer to the parent dentry for this file. This should be a
377 * directory dentry if set. If this parameter is NULL, then the
378 * file will be created in the root of the debugfs filesystem.
379 * @data: a pointer to something that the caller will want to get to later
380 * on. The inode.i_private pointer will point to this value on
381 * the open() call.
382 * @fops: a pointer to a struct file_operations that should be used for
383 * this file.
384 *
385 * debugfs_create_file_unsafe() is completely analogous to
386 * debugfs_create_file(), the only difference being that the fops
387 * handed it will not get protected against file removals by the
388 * debugfs core.
389 *
390 * It is your responsibility to protect your struct file_operation
391 * methods against file removals by means of debugfs_use_file_start()
392 * and debugfs_use_file_finish(). ->open() is still protected by
393 * debugfs though.
394 *
395 * Any struct file_operations defined by means of
396 * DEFINE_DEBUGFS_ATTRIBUTE() is protected against file removals and
397 * thus, may be used here.
398 */
399struct dentry *debugfs_create_file_unsafe(const char *name, umode_t mode,
400 struct dentry *parent, void *data,
401 const struct file_operations *fops)
402{
341 403
342 inode->i_mode = mode; 404 return __debugfs_create_file(name, mode, parent, data,
343 inode->i_fop = fops ? fops : &debugfs_file_operations; 405 fops ? &debugfs_open_proxy_file_operations :
344 inode->i_private = data; 406 &debugfs_noop_file_operations,
345 d_instantiate(dentry, inode); 407 fops);
346 fsnotify_create(d_inode(dentry->d_parent), dentry);
347 return end_creating(dentry);
348} 408}
349EXPORT_SYMBOL_GPL(debugfs_create_file); 409EXPORT_SYMBOL_GPL(debugfs_create_file_unsafe);
350 410
351/** 411/**
352 * debugfs_create_file_size - create a file in the debugfs filesystem 412 * debugfs_create_file_size - create a file in the debugfs filesystem
@@ -461,7 +521,11 @@ struct dentry *debugfs_create_automount(const char *name,
461 inode->i_flags |= S_AUTOMOUNT; 521 inode->i_flags |= S_AUTOMOUNT;
462 inode->i_private = data; 522 inode->i_private = data;
463 dentry->d_fsdata = (void *)f; 523 dentry->d_fsdata = (void *)f;
524 /* directory inodes start off with i_nlink == 2 (for "." entry) */
525 inc_nlink(inode);
464 d_instantiate(dentry, inode); 526 d_instantiate(dentry, inode);
527 inc_nlink(d_inode(dentry->d_parent));
528 fsnotify_mkdir(d_inode(dentry->d_parent), dentry);
465 return end_creating(dentry); 529 return end_creating(dentry);
466} 530}
467EXPORT_SYMBOL(debugfs_create_automount); 531EXPORT_SYMBOL(debugfs_create_automount);
@@ -565,6 +629,8 @@ void debugfs_remove(struct dentry *dentry)
565 inode_unlock(d_inode(parent)); 629 inode_unlock(d_inode(parent));
566 if (!ret) 630 if (!ret)
567 simple_release_fs(&debugfs_mount, &debugfs_mount_count); 631 simple_release_fs(&debugfs_mount, &debugfs_mount_count);
632
633 synchronize_srcu(&debugfs_srcu);
568} 634}
569EXPORT_SYMBOL_GPL(debugfs_remove); 635EXPORT_SYMBOL_GPL(debugfs_remove);
570 636
@@ -642,6 +708,8 @@ void debugfs_remove_recursive(struct dentry *dentry)
642 if (!__debugfs_remove(child, parent)) 708 if (!__debugfs_remove(child, parent))
643 simple_release_fs(&debugfs_mount, &debugfs_mount_count); 709 simple_release_fs(&debugfs_mount, &debugfs_mount_count);
644 inode_unlock(d_inode(parent)); 710 inode_unlock(d_inode(parent));
711
712 synchronize_srcu(&debugfs_srcu);
645} 713}
646EXPORT_SYMBOL_GPL(debugfs_remove_recursive); 714EXPORT_SYMBOL_GPL(debugfs_remove_recursive);
647 715