UPSTREAM: debugfs: add debugfs_lookup()
authorOmar Sandoval <osandov@fb.com>
Tue, 31 Jan 2017 22:53:17 +0000 (14:53 -0800)
committerHuang, Tao <huangtao@rock-chips.com>
Wed, 26 Jul 2017 07:07:32 +0000 (15:07 +0800)
We don't always have easy access to the dentry of a file or directory we
created in debugfs. Add a helper which allows us to get a dentry we
previously created.

The motivation for this change is a problem with blktrace and the blk-mq
debugfs entries introduced in 07e4fead45e6 ("blk-mq: create debugfs
directory tree"). Namely, in some cases, the directory that blktrace
needs to create may already exist, but in other cases, it may not. We
_could_ rely on a bunch of implied knowledge to decide whether to create
the directory or not, but it's much cleaner on our end to just look it
up.

Signed-off-by: Omar Sandoval <osandov@fb.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Jens Axboe <axboe@fb.com>
(cherry picked from commit a7c5437b0bbec5165df6eb1efc5e37dc40b9e05d)

Change-Id: I77b6f2c7df32f904099d23771a53065315cfdc12

fs/debugfs/inode.c
include/linux/debugfs.h

index 0f5d05bf213140ccc10106bbc0ad3894d2bb9538..31b7265f2e7d7d522d4550280e85a451beebff9f 100644 (file)
@@ -242,6 +242,42 @@ static struct file_system_type debug_fs_type = {
 };
 MODULE_ALIAS_FS("debugfs");
 
+/**
+ * debugfs_lookup() - look up an existing debugfs file
+ * @name: a pointer to a string containing the name of the file to look up.
+ * @parent: a pointer to the parent dentry of the file.
+ *
+ * This function will return a pointer to a dentry if it succeeds.  If the file
+ * doesn't exist or an error occurs, %NULL will be returned.  The returned
+ * dentry must be passed to dput() when it is no longer needed.
+ *
+ * If debugfs is not enabled in the kernel, the value -%ENODEV will be
+ * returned.
+ */
+struct dentry *debugfs_lookup(const char *name, struct dentry *parent)
+{
+       struct dentry *dentry;
+
+       if (IS_ERR(parent))
+               return NULL;
+
+       if (!parent)
+               parent = debugfs_mount->mnt_root;
+
+       inode_lock(d_inode(parent));
+       dentry = lookup_one_len(name, parent, strlen(name));
+       inode_unlock(d_inode(parent));
+
+       if (IS_ERR(dentry))
+               return NULL;
+       if (!d_really_is_positive(dentry)) {
+               dput(dentry);
+               return NULL;
+       }
+       return dentry;
+}
+EXPORT_SYMBOL_GPL(debugfs_lookup);
+
 static struct dentry *start_creating(const char *name, struct dentry *parent)
 {
        struct dentry *dentry;
index 19c066dce1dab2e0a4dfab9f2851d6998d0f8716..33d708d91a5ca4203da4e83db84be16357e5acb5 100644 (file)
@@ -46,6 +46,8 @@ extern struct dentry *arch_debugfs_dir;
 /* declared over in file.c */
 extern const struct file_operations debugfs_file_operations;
 
+struct dentry *debugfs_lookup(const char *name, struct dentry *parent);
+
 struct dentry *debugfs_create_file(const char *name, umode_t mode,
                                   struct dentry *parent, void *data,
                                   const struct file_operations *fops);
@@ -134,6 +136,12 @@ ssize_t debugfs_write_file_bool(struct file *file, const char __user *user_buf,
  * want to duplicate the design decision mistakes of procfs and devfs again.
  */
 
+static inline struct dentry *debugfs_lookup(const char *name,
+                                           struct dentry *parent)
+{
+       return ERR_PTR(-ENODEV);
+}
+
 static inline struct dentry *debugfs_create_file(const char *name, umode_t mode,
                                        struct dentry *parent, void *data,
                                        const struct file_operations *fops)