diff options
| -rw-r--r-- | fs/debugfs/inode.c | 48 | ||||
| -rw-r--r-- | include/linux/debugfs.h | 5 |
2 files changed, 53 insertions, 0 deletions
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 1219dff8e18f..957c40ce09f6 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
| @@ -175,6 +175,18 @@ static const struct super_operations debugfs_super_operations = { | |||
| 175 | .show_options = debugfs_show_options, | 175 | .show_options = debugfs_show_options, |
| 176 | }; | 176 | }; |
| 177 | 177 | ||
| 178 | static struct vfsmount *debugfs_automount(struct path *path) | ||
| 179 | { | ||
| 180 | struct vfsmount *(*f)(void *); | ||
| 181 | f = (struct vfsmount *(*)(void *))path->dentry->d_fsdata; | ||
| 182 | return f(path->dentry->d_inode->i_private); | ||
| 183 | } | ||
| 184 | |||
| 185 | static const struct dentry_operations debugfs_dops = { | ||
| 186 | .d_delete = always_delete_dentry, | ||
| 187 | .d_automount = debugfs_automount, | ||
| 188 | }; | ||
| 189 | |||
| 178 | static int debug_fill_super(struct super_block *sb, void *data, int silent) | 190 | static int debug_fill_super(struct super_block *sb, void *data, int silent) |
| 179 | { | 191 | { |
| 180 | static struct tree_descr debug_files[] = {{""}}; | 192 | static struct tree_descr debug_files[] = {{""}}; |
| @@ -199,6 +211,7 @@ static int debug_fill_super(struct super_block *sb, void *data, int silent) | |||
| 199 | goto fail; | 211 | goto fail; |
| 200 | 212 | ||
| 201 | sb->s_op = &debugfs_super_operations; | 213 | sb->s_op = &debugfs_super_operations; |
| 214 | sb->s_d_op = &debugfs_dops; | ||
| 202 | 215 | ||
| 203 | debugfs_apply_options(sb); | 216 | debugfs_apply_options(sb); |
| 204 | 217 | ||
| @@ -368,6 +381,41 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent) | |||
| 368 | EXPORT_SYMBOL_GPL(debugfs_create_dir); | 381 | EXPORT_SYMBOL_GPL(debugfs_create_dir); |
| 369 | 382 | ||
| 370 | /** | 383 | /** |
| 384 | * debugfs_create_automount - create automount point in the debugfs filesystem | ||
| 385 | * @name: a pointer to a string containing the name of the file to create. | ||
| 386 | * @parent: a pointer to the parent dentry for this file. This should be a | ||
| 387 | * directory dentry if set. If this parameter is NULL, then the | ||
| 388 | * file will be created in the root of the debugfs filesystem. | ||
| 389 | * @f: function to be called when pathname resolution steps on that one. | ||
| 390 | * @data: opaque argument to pass to f(). | ||
| 391 | * | ||
| 392 | * @f should return what ->d_automount() would. | ||
| 393 | */ | ||
| 394 | struct dentry *debugfs_create_automount(const char *name, | ||
| 395 | struct dentry *parent, | ||
| 396 | struct vfsmount *(*f)(void *), | ||
| 397 | void *data) | ||
| 398 | { | ||
| 399 | struct dentry *dentry = start_creating(name, parent); | ||
| 400 | struct inode *inode; | ||
| 401 | |||
| 402 | if (IS_ERR(dentry)) | ||
| 403 | return NULL; | ||
| 404 | |||
| 405 | inode = debugfs_get_inode(dentry->d_sb); | ||
| 406 | if (unlikely(!inode)) | ||
| 407 | return failed_creating(dentry); | ||
| 408 | |||
| 409 | inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; | ||
| 410 | inode->i_flags |= S_AUTOMOUNT; | ||
| 411 | inode->i_private = data; | ||
| 412 | dentry->d_fsdata = (void *)f; | ||
| 413 | d_instantiate(dentry, inode); | ||
| 414 | return end_creating(dentry); | ||
| 415 | } | ||
| 416 | EXPORT_SYMBOL(debugfs_create_automount); | ||
| 417 | |||
| 418 | /** | ||
| 371 | * debugfs_create_symlink- create a symbolic link in the debugfs filesystem | 419 | * debugfs_create_symlink- create a symbolic link in the debugfs filesystem |
| 372 | * @name: a pointer to a string containing the name of the symbolic link to | 420 | * @name: a pointer to a string containing the name of the symbolic link to |
| 373 | * create. | 421 | * create. |
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index da4c4983adbe..ea149a24a1f2 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h | |||
| @@ -56,6 +56,11 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent); | |||
| 56 | struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, | 56 | struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, |
| 57 | const char *dest); | 57 | const char *dest); |
| 58 | 58 | ||
| 59 | struct dentry *debugfs_create_automount(const char *name, | ||
| 60 | struct dentry *parent, | ||
| 61 | struct vfsmount *(*f)(void *), | ||
| 62 | void *data); | ||
| 63 | |||
| 59 | void debugfs_remove(struct dentry *dentry); | 64 | void debugfs_remove(struct dentry *dentry); |
| 60 | void debugfs_remove_recursive(struct dentry *dentry); | 65 | void debugfs_remove_recursive(struct dentry *dentry); |
| 61 | 66 | ||
