diff options
author | Omar Sandoval <osandov@fb.com> | 2017-01-31 17:53:17 -0500 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2017-02-02 12:20:16 -0500 |
commit | a7c5437b0bbec5165df6eb1efc5e37dc40b9e05d (patch) | |
tree | d37659f3ab5b8baccafe06442ca3fa6a1048503c | |
parent | 0dba1314d4f81115dce711292ec7981d17231064 (diff) |
debugfs: add debugfs_lookup()
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>
-rw-r--r-- | fs/debugfs/inode.c | 36 | ||||
-rw-r--r-- | include/linux/debugfs.h | 8 |
2 files changed, 44 insertions, 0 deletions
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index f17fcf89e18e..7fb1732a3630 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
@@ -248,6 +248,42 @@ static struct file_system_type debug_fs_type = { | |||
248 | }; | 248 | }; |
249 | MODULE_ALIAS_FS("debugfs"); | 249 | MODULE_ALIAS_FS("debugfs"); |
250 | 250 | ||
251 | /** | ||
252 | * debugfs_lookup() - look up an existing debugfs file | ||
253 | * @name: a pointer to a string containing the name of the file to look up. | ||
254 | * @parent: a pointer to the parent dentry of the file. | ||
255 | * | ||
256 | * This function will return a pointer to a dentry if it succeeds. If the file | ||
257 | * doesn't exist or an error occurs, %NULL will be returned. The returned | ||
258 | * dentry must be passed to dput() when it is no longer needed. | ||
259 | * | ||
260 | * If debugfs is not enabled in the kernel, the value -%ENODEV will be | ||
261 | * returned. | ||
262 | */ | ||
263 | struct dentry *debugfs_lookup(const char *name, struct dentry *parent) | ||
264 | { | ||
265 | struct dentry *dentry; | ||
266 | |||
267 | if (IS_ERR(parent)) | ||
268 | return NULL; | ||
269 | |||
270 | if (!parent) | ||
271 | parent = debugfs_mount->mnt_root; | ||
272 | |||
273 | inode_lock(d_inode(parent)); | ||
274 | dentry = lookup_one_len(name, parent, strlen(name)); | ||
275 | inode_unlock(d_inode(parent)); | ||
276 | |||
277 | if (IS_ERR(dentry)) | ||
278 | return NULL; | ||
279 | if (!d_really_is_positive(dentry)) { | ||
280 | dput(dentry); | ||
281 | return NULL; | ||
282 | } | ||
283 | return dentry; | ||
284 | } | ||
285 | EXPORT_SYMBOL_GPL(debugfs_lookup); | ||
286 | |||
251 | static struct dentry *start_creating(const char *name, struct dentry *parent) | 287 | static struct dentry *start_creating(const char *name, struct dentry *parent) |
252 | { | 288 | { |
253 | struct dentry *dentry; | 289 | struct dentry *dentry; |
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index 014cc564d1c4..c0befcf41b58 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h | |||
@@ -80,6 +80,8 @@ static const struct file_operations __fops = { \ | |||
80 | 80 | ||
81 | #if defined(CONFIG_DEBUG_FS) | 81 | #if defined(CONFIG_DEBUG_FS) |
82 | 82 | ||
83 | struct dentry *debugfs_lookup(const char *name, struct dentry *parent); | ||
84 | |||
83 | struct dentry *debugfs_create_file(const char *name, umode_t mode, | 85 | struct dentry *debugfs_create_file(const char *name, umode_t mode, |
84 | struct dentry *parent, void *data, | 86 | struct dentry *parent, void *data, |
85 | const struct file_operations *fops); | 87 | const struct file_operations *fops); |
@@ -181,6 +183,12 @@ ssize_t debugfs_write_file_bool(struct file *file, const char __user *user_buf, | |||
181 | * want to duplicate the design decision mistakes of procfs and devfs again. | 183 | * want to duplicate the design decision mistakes of procfs and devfs again. |
182 | */ | 184 | */ |
183 | 185 | ||
186 | static inline struct dentry *debugfs_lookup(const char *name, | ||
187 | struct dentry *parent) | ||
188 | { | ||
189 | return ERR_PTR(-ENODEV); | ||
190 | } | ||
191 | |||
184 | static inline struct dentry *debugfs_create_file(const char *name, umode_t mode, | 192 | static inline struct dentry *debugfs_create_file(const char *name, umode_t mode, |
185 | struct dentry *parent, void *data, | 193 | struct dentry *parent, void *data, |
186 | const struct file_operations *fops) | 194 | const struct file_operations *fops) |