aboutsummaryrefslogtreecommitdiffstats
path: root/fs/debugfs/inode.c
diff options
context:
space:
mode:
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