3bce94fd5f4c0 (Greg Kroah-Hartman 2017-11-07 16:59:23 +0100 1) // SPDX-License-Identifier: GPL-2.0
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2) /*
bd33d12fba60d (Harry Wei 2011-07-16 16:45:13 +0800 3) * inode.c - part of debugfs, a tiny little debug file system
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 4) *
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 5) * Copyright (C) 2004,2019 Greg Kroah-Hartman <greg@kroah.com>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 6) * Copyright (C) 2004 IBM Inc.
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 7) * Copyright (C) 2019 Linux Foundation <gregkh@linuxfoundation.org>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 8) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 9) * debugfs is for people to use instead of /proc or /sys.
e1511a840a33f (Mauro Carvalho Chehab 2017-05-14 12:09:53 -0300 10) * See ./Documentation/core-api/kernel-api.rst for more details.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 11) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 12)
d03ae4778b3b6 (Greg Kroah-Hartman 2019-07-03 09:16:52 +0200 13) #define pr_fmt(fmt) "debugfs: " fmt
d03ae4778b3b6 (Greg Kroah-Hartman 2019-07-03 09:16:52 +0200 14)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 15) #include <linux/module.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 16) #include <linux/fs.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 17) #include <linux/mount.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 18) #include <linux/pagemap.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 19) #include <linux/init.h>
4d8ebddcc525a (Randy Dunlap 2006-11-25 11:09:26 -0800 20) #include <linux/kobject.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 21) #include <linux/namei.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 22) #include <linux/debugfs.h>
4f36557fbe4ab (Mathieu Desnoyers 2006-11-24 13:45:37 -0500 23) #include <linux/fsnotify.h>
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 24) #include <linux/string.h>
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 25) #include <linux/seq_file.h>
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 26) #include <linux/parser.h>
92562927826fc (Mimi Zohar 2008-10-07 14:00:12 -0400 27) #include <linux/magic.h>
5a0e3ad6af866 (Tejun Heo 2010-03-24 17:04:11 +0900 28) #include <linux/slab.h>
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 29) #include <linux/security.h>
9fd4dcece43a5 (Nicolai Stange 2016-03-22 14:11:13 +0100 30)
9fd4dcece43a5 (Nicolai Stange 2016-03-22 14:11:13 +0100 31) #include "internal.h"
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 32)
82aceae4f0d42 (Kees Cook 2012-08-27 13:32:15 -0700 33) #define DEBUGFS_DEFAULT_MODE 0700
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 34)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 35) static struct vfsmount *debugfs_mount;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 36) static int debugfs_mount_count;
c0f92ba99bdea (Frederic Weisbecker 2009-03-22 23:10:44 +0100 37) static bool debugfs_registered;
312723a0b34d6 (Kees Cook 2021-04-05 14:39:59 -0700 38) static unsigned int debugfs_allow __ro_after_init = DEFAULT_DEBUGFS_ALLOW_BITS;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 39)
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 40) /*
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 41) * Don't allow access attributes to be changed whilst the kernel is locked down
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 42) * so that we can use the file mode as part of a heuristic to determine whether
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 43) * to lock down individual files.
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 44) */
549c7297717c3 (Christian Brauner 2021-01-21 14:19:43 +0100 45) static int debugfs_setattr(struct user_namespace *mnt_userns,
549c7297717c3 (Christian Brauner 2021-01-21 14:19:43 +0100 46) struct dentry *dentry, struct iattr *ia)
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 47) {
5881fa8dc2de9 (Ondrej Mosnacek 2021-05-07 14:53:04 +0200 48) int ret;
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 49)
5881fa8dc2de9 (Ondrej Mosnacek 2021-05-07 14:53:04 +0200 50) if (ia->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)) {
5881fa8dc2de9 (Ondrej Mosnacek 2021-05-07 14:53:04 +0200 51) ret = security_locked_down(LOCKDOWN_DEBUGFS);
5881fa8dc2de9 (Ondrej Mosnacek 2021-05-07 14:53:04 +0200 52) if (ret)
5881fa8dc2de9 (Ondrej Mosnacek 2021-05-07 14:53:04 +0200 53) return ret;
5881fa8dc2de9 (Ondrej Mosnacek 2021-05-07 14:53:04 +0200 54) }
549c7297717c3 (Christian Brauner 2021-01-21 14:19:43 +0100 55) return simple_setattr(&init_user_ns, dentry, ia);
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 56) }
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 57)
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 58) static const struct inode_operations debugfs_file_inode_operations = {
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 59) .setattr = debugfs_setattr,
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 60) };
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 61) static const struct inode_operations debugfs_dir_inode_operations = {
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 62) .lookup = simple_lookup,
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 63) .setattr = debugfs_setattr,
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 64) };
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 65) static const struct inode_operations debugfs_symlink_inode_operations = {
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 66) .get_link = simple_get_link,
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 67) .setattr = debugfs_setattr,
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 68) };
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 69)
edac65eaf8d5c (Al Viro 2015-01-25 14:36:18 -0500 70) static struct inode *debugfs_get_inode(struct super_block *sb)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 71) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 72) struct inode *inode = new_inode(sb);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 73) if (inode) {
85fe4025c616a (Christoph Hellwig 2010-10-23 11:19:54 -0400 74) inode->i_ino = get_next_ino();
1b48b530dac3e (Deepa Dinamani 2016-02-22 07:17:47 -0800 75) inode->i_atime = inode->i_mtime =
c2050a454c7f1 (Deepa Dinamani 2016-09-14 07:48:06 -0700 76) inode->i_ctime = current_time(inode);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 77) }
88e412ea5ebc3 (Rahul Bedarkar 2014-06-06 23:12:04 +0530 78) return inode;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 79) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 80)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 81) struct debugfs_mount_opts {
7dc05881b6479 (Eric W. Biederman 2012-04-03 14:01:31 -0700 82) kuid_t uid;
7dc05881b6479 (Eric W. Biederman 2012-04-03 14:01:31 -0700 83) kgid_t gid;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 84) umode_t mode;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 85) };
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 86)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 87) enum {
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 88) Opt_uid,
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 89) Opt_gid,
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 90) Opt_mode,
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 91) Opt_err
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 92) };
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 93)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 94) static const match_table_t tokens = {
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 95) {Opt_uid, "uid=%u"},
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 96) {Opt_gid, "gid=%u"},
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 97) {Opt_mode, "mode=%o"},
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 98) {Opt_err, NULL}
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 99) };
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 100)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 101) struct debugfs_fs_info {
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 102) struct debugfs_mount_opts mount_opts;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 103) };
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 104)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 105) static int debugfs_parse_options(char *data, struct debugfs_mount_opts *opts)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 106) {
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 107) substring_t args[MAX_OPT_ARGS];
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 108) int option;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 109) int token;
7dc05881b6479 (Eric W. Biederman 2012-04-03 14:01:31 -0700 110) kuid_t uid;
7dc05881b6479 (Eric W. Biederman 2012-04-03 14:01:31 -0700 111) kgid_t gid;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 112) char *p;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 113)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 114) opts->mode = DEBUGFS_DEFAULT_MODE;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 115)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 116) while ((p = strsep(&data, ",")) != NULL) {
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 117) if (!*p)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 118) continue;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 119)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 120) token = match_token(p, tokens, args);
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 121) switch (token) {
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 122) case Opt_uid:
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 123) if (match_int(&args[0], &option))
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 124) return -EINVAL;
7dc05881b6479 (Eric W. Biederman 2012-04-03 14:01:31 -0700 125) uid = make_kuid(current_user_ns(), option);
7dc05881b6479 (Eric W. Biederman 2012-04-03 14:01:31 -0700 126) if (!uid_valid(uid))
7dc05881b6479 (Eric W. Biederman 2012-04-03 14:01:31 -0700 127) return -EINVAL;
7dc05881b6479 (Eric W. Biederman 2012-04-03 14:01:31 -0700 128) opts->uid = uid;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 129) break;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 130) case Opt_gid:
f1688e0431d3a (Dave Reisner 2013-01-02 08:54:37 -0500 131) if (match_int(&args[0], &option))
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 132) return -EINVAL;
7dc05881b6479 (Eric W. Biederman 2012-04-03 14:01:31 -0700 133) gid = make_kgid(current_user_ns(), option);
7dc05881b6479 (Eric W. Biederman 2012-04-03 14:01:31 -0700 134) if (!gid_valid(gid))
7dc05881b6479 (Eric W. Biederman 2012-04-03 14:01:31 -0700 135) return -EINVAL;
7dc05881b6479 (Eric W. Biederman 2012-04-03 14:01:31 -0700 136) opts->gid = gid;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 137) break;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 138) case Opt_mode:
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 139) if (match_octal(&args[0], &option))
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 140) return -EINVAL;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 141) opts->mode = option & S_IALLUGO;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 142) break;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 143) /*
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 144) * We might like to report bad mount options here;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 145) * but traditionally debugfs has ignored all mount options
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 146) */
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 147) }
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 148) }
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 149)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 150) return 0;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 151) }
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 152)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 153) static int debugfs_apply_options(struct super_block *sb)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 154) {
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 155) struct debugfs_fs_info *fsi = sb->s_fs_info;
2b0143b5c986b (David Howells 2015-03-17 22:25:59 +0000 156) struct inode *inode = d_inode(sb->s_root);
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 157) struct debugfs_mount_opts *opts = &fsi->mount_opts;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 158)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 159) inode->i_mode &= ~S_IALLUGO;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 160) inode->i_mode |= opts->mode;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 161)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 162) inode->i_uid = opts->uid;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 163) inode->i_gid = opts->gid;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 164)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 165) return 0;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 166) }
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 167)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 168) static int debugfs_remount(struct super_block *sb, int *flags, char *data)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 169) {
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 170) int err;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 171) struct debugfs_fs_info *fsi = sb->s_fs_info;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 172)
02b9984d64087 (Theodore Ts'o 2014-03-13 10:14:33 -0400 173) sync_filesystem(sb);
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 174) err = debugfs_parse_options(data, &fsi->mount_opts);
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 175) if (err)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 176) goto fail;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 177)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 178) debugfs_apply_options(sb);
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 179)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 180) fail:
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 181) return err;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 182) }
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 183)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 184) static int debugfs_show_options(struct seq_file *m, struct dentry *root)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 185) {
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 186) struct debugfs_fs_info *fsi = root->d_sb->s_fs_info;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 187) struct debugfs_mount_opts *opts = &fsi->mount_opts;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 188)
7dc05881b6479 (Eric W. Biederman 2012-04-03 14:01:31 -0700 189) if (!uid_eq(opts->uid, GLOBAL_ROOT_UID))
7dc05881b6479 (Eric W. Biederman 2012-04-03 14:01:31 -0700 190) seq_printf(m, ",uid=%u",
7dc05881b6479 (Eric W. Biederman 2012-04-03 14:01:31 -0700 191) from_kuid_munged(&init_user_ns, opts->uid));
7dc05881b6479 (Eric W. Biederman 2012-04-03 14:01:31 -0700 192) if (!gid_eq(opts->gid, GLOBAL_ROOT_GID))
7dc05881b6479 (Eric W. Biederman 2012-04-03 14:01:31 -0700 193) seq_printf(m, ",gid=%u",
7dc05881b6479 (Eric W. Biederman 2012-04-03 14:01:31 -0700 194) from_kgid_munged(&init_user_ns, opts->gid));
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 195) if (opts->mode != DEBUGFS_DEFAULT_MODE)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 196) seq_printf(m, ",mode=%o", opts->mode);
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 197)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 198) return 0;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 199) }
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 200)
6234ddf429ef8 (Al Viro 2019-04-14 23:19:45 -0400 201) static void debugfs_free_inode(struct inode *inode)
0db59e59299f0 (Al Viro 2015-02-21 22:05:11 -0500 202) {
0db59e59299f0 (Al Viro 2015-02-21 22:05:11 -0500 203) if (S_ISLNK(inode->i_mode))
5723cb01f0295 (Al Viro 2015-05-02 10:27:18 -0400 204) kfree(inode->i_link);
93b919da64c15 (Al Viro 2019-03-26 01:43:37 +0000 205) free_inode_nonrcu(inode);
93b919da64c15 (Al Viro 2019-03-26 01:43:37 +0000 206) }
93b919da64c15 (Al Viro 2019-03-26 01:43:37 +0000 207)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 208) static const struct super_operations debugfs_super_operations = {
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 209) .statfs = simple_statfs,
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 210) .remount_fs = debugfs_remount,
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 211) .show_options = debugfs_show_options,
6234ddf429ef8 (Al Viro 2019-04-14 23:19:45 -0400 212) .free_inode = debugfs_free_inode,
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 213) };
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 214)
7c8d469877b16 (Nicolai Stange 2017-10-31 00:15:47 +0100 215) static void debugfs_release_dentry(struct dentry *dentry)
7c8d469877b16 (Nicolai Stange 2017-10-31 00:15:47 +0100 216) {
7d39bc50c47b3 (Nicolai Stange 2017-10-31 00:15:54 +0100 217) void *fsd = dentry->d_fsdata;
7d39bc50c47b3 (Nicolai Stange 2017-10-31 00:15:54 +0100 218)
7d39bc50c47b3 (Nicolai Stange 2017-10-31 00:15:54 +0100 219) if (!((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT))
7d39bc50c47b3 (Nicolai Stange 2017-10-31 00:15:54 +0100 220) kfree(dentry->d_fsdata);
7c8d469877b16 (Nicolai Stange 2017-10-31 00:15:47 +0100 221) }
7c8d469877b16 (Nicolai Stange 2017-10-31 00:15:47 +0100 222)
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 223) static struct vfsmount *debugfs_automount(struct path *path)
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 224) {
93faccbbfa958 (Eric W. Biederman 2017-02-01 06:06:16 +1300 225) debugfs_automount_t f;
93faccbbfa958 (Eric W. Biederman 2017-02-01 06:06:16 +1300 226) f = (debugfs_automount_t)path->dentry->d_fsdata;
93faccbbfa958 (Eric W. Biederman 2017-02-01 06:06:16 +1300 227) return f(path->dentry, d_inode(path->dentry)->i_private);
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 228) }
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 229)
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 230) static const struct dentry_operations debugfs_dops = {
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 231) .d_delete = always_delete_dentry,
7c8d469877b16 (Nicolai Stange 2017-10-31 00:15:47 +0100 232) .d_release = debugfs_release_dentry,
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 233) .d_automount = debugfs_automount,
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 234) };
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 235)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 236) static int debug_fill_super(struct super_block *sb, void *data, int silent)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 237) {
cda37124f4e95 (Eric Biggers 2017-03-25 21:15:37 -0700 238) static const struct tree_descr debug_files[] = {{""}};
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 239) struct debugfs_fs_info *fsi;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 240) int err;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 241)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 242) fsi = kzalloc(sizeof(struct debugfs_fs_info), GFP_KERNEL);
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 243) sb->s_fs_info = fsi;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 244) if (!fsi) {
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 245) err = -ENOMEM;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 246) goto fail;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 247) }
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 248)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 249) err = debugfs_parse_options(data, &fsi->mount_opts);
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 250) if (err)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 251) goto fail;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 252)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 253) err = simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 254) if (err)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 255) goto fail;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 256)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 257) sb->s_op = &debugfs_super_operations;
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 258) sb->s_d_op = &debugfs_dops;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 259)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 260) debugfs_apply_options(sb);
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 261)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 262) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 263)
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 264) fail:
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 265) kfree(fsi);
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 266) sb->s_fs_info = NULL;
d6e486868cde5 (Ludwig Nussel 2012-01-25 11:52:28 +0100 267) return err;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 268) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 269)
fc14f2fef682d (Al Viro 2010-07-25 01:48:30 +0400 270) static struct dentry *debug_mount(struct file_system_type *fs_type,
454e2398be9b9 (David Howells 2006-06-23 02:02:57 -0700 271) int flags, const char *dev_name,
fc14f2fef682d (Al Viro 2010-07-25 01:48:30 +0400 272) void *data)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 273) {
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 274) if (!(debugfs_allow & DEBUGFS_ALLOW_API))
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 275) return ERR_PTR(-EPERM);
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 276)
fc14f2fef682d (Al Viro 2010-07-25 01:48:30 +0400 277) return mount_single(fs_type, flags, data, debug_fill_super);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 278) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 279)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 280) static struct file_system_type debug_fs_type = {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 281) .owner = THIS_MODULE,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 282) .name = "debugfs",
fc14f2fef682d (Al Viro 2010-07-25 01:48:30 +0400 283) .mount = debug_mount,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 284) .kill_sb = kill_litter_super,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 285) };
7f78e03513940 (Eric W. Biederman 2013-03-02 19:39:14 -0800 286) MODULE_ALIAS_FS("debugfs");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 287)
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 288) /**
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 289) * debugfs_lookup() - look up an existing debugfs file
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 290) * @name: a pointer to a string containing the name of the file to look up.
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 291) * @parent: a pointer to the parent dentry of the file.
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 292) *
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 293) * This function will return a pointer to a dentry if it succeeds. If the file
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 294) * doesn't exist or an error occurs, %NULL will be returned. The returned
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 295) * dentry must be passed to dput() when it is no longer needed.
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 296) *
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 297) * If debugfs is not enabled in the kernel, the value -%ENODEV will be
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 298) * returned.
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 299) */
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 300) struct dentry *debugfs_lookup(const char *name, struct dentry *parent)
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 301) {
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 302) struct dentry *dentry;
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 303)
bc6de804d36b3 (Greg Kroah-Hartman 2021-02-18 11:08:17 +0100 304) if (!debugfs_initialized() || IS_ERR_OR_NULL(name) || IS_ERR(parent))
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 305) return NULL;
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 306)
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 307) if (!parent)
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 308) parent = debugfs_mount->mnt_root;
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 309)
6c2d4798a8d16 (Al Viro 2019-10-31 01:21:58 -0400 310) dentry = lookup_positive_unlocked(name, parent, strlen(name));
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 311) if (IS_ERR(dentry))
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 312) return NULL;
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 313) return dentry;
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 314) }
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 315) EXPORT_SYMBOL_GPL(debugfs_lookup);
a7c5437b0bbec (Omar Sandoval 2017-01-31 14:53:17 -0800 316)
190afd81e4a5f (Al Viro 2015-01-25 13:55:55 -0500 317) static struct dentry *start_creating(const char *name, struct dentry *parent)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 318) {
190afd81e4a5f (Al Viro 2015-01-25 13:55:55 -0500 319) struct dentry *dentry;
cfa57c11b0d5a (Al Viro 2012-06-09 20:33:28 -0400 320) int error;
cfa57c11b0d5a (Al Viro 2012-06-09 20:33:28 -0400 321)
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 322) if (!(debugfs_allow & DEBUGFS_ALLOW_API))
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 323) return ERR_PTR(-EPERM);
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 324)
56348560d495d (Greg Kroah-Hartman 2021-02-18 11:08:18 +0100 325) if (!debugfs_initialized())
56348560d495d (Greg Kroah-Hartman 2021-02-18 11:08:18 +0100 326) return ERR_PTR(-ENOENT);
56348560d495d (Greg Kroah-Hartman 2021-02-18 11:08:18 +0100 327)
d03ae4778b3b6 (Greg Kroah-Hartman 2019-07-03 09:16:52 +0200 328) pr_debug("creating file '%s'\n", name);
cfa57c11b0d5a (Al Viro 2012-06-09 20:33:28 -0400 329)
c9e15f25f514a (Greg KH 2015-03-30 14:59:15 +0200 330) if (IS_ERR(parent))
c9e15f25f514a (Greg KH 2015-03-30 14:59:15 +0200 331) return parent;
c9e15f25f514a (Greg KH 2015-03-30 14:59:15 +0200 332)
cfa57c11b0d5a (Al Viro 2012-06-09 20:33:28 -0400 333) error = simple_pin_fs(&debug_fs_type, &debugfs_mount,
cfa57c11b0d5a (Al Viro 2012-06-09 20:33:28 -0400 334) &debugfs_mount_count);
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 335) if (error) {
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 336) pr_err("Unable to pin filesystem for file '%s'\n", name);
190afd81e4a5f (Al Viro 2015-01-25 13:55:55 -0500 337) return ERR_PTR(error);
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 338) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 339)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 340) /* If the parent is not specified, we create it in the root.
88e412ea5ebc3 (Rahul Bedarkar 2014-06-06 23:12:04 +0530 341) * We need the root dentry to do this, which is in the super
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 342) * block. A pointer to that is in the struct vfsmount that we
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 343) * have around.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 344) */
ef52c75e4b160 (Al Viro 2010-01-25 04:50:43 -0500 345) if (!parent)
4c1d5a64f134b (Al Viro 2011-12-07 18:21:57 -0500 346) parent = debugfs_mount->mnt_root;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 347)
5955102c9984f (Al Viro 2016-01-22 15:40:57 -0500 348) inode_lock(d_inode(parent));
a3d1e7eb5abe3 (Al Viro 2019-11-18 09:43:10 -0500 349) if (unlikely(IS_DEADDIR(d_inode(parent))))
a3d1e7eb5abe3 (Al Viro 2019-11-18 09:43:10 -0500 350) dentry = ERR_PTR(-ENOENT);
a3d1e7eb5abe3 (Al Viro 2019-11-18 09:43:10 -0500 351) else
a3d1e7eb5abe3 (Al Viro 2019-11-18 09:43:10 -0500 352) dentry = lookup_one_len(name, parent, strlen(name));
2b0143b5c986b (David Howells 2015-03-17 22:25:59 +0000 353) if (!IS_ERR(dentry) && d_really_is_positive(dentry)) {
c33d442328f55 (Greg Kroah-Hartman 2019-07-06 17:42:56 +0200 354) if (d_is_dir(dentry))
c33d442328f55 (Greg Kroah-Hartman 2019-07-06 17:42:56 +0200 355) pr_err("Directory '%s' with parent '%s' already present!\n",
c33d442328f55 (Greg Kroah-Hartman 2019-07-06 17:42:56 +0200 356) name, parent->d_name.name);
c33d442328f55 (Greg Kroah-Hartman 2019-07-06 17:42:56 +0200 357) else
c33d442328f55 (Greg Kroah-Hartman 2019-07-06 17:42:56 +0200 358) pr_err("File '%s' in directory '%s' already present!\n",
c33d442328f55 (Greg Kroah-Hartman 2019-07-06 17:42:56 +0200 359) name, parent->d_name.name);
cfa57c11b0d5a (Al Viro 2012-06-09 20:33:28 -0400 360) dput(dentry);
190afd81e4a5f (Al Viro 2015-01-25 13:55:55 -0500 361) dentry = ERR_PTR(-EEXIST);
190afd81e4a5f (Al Viro 2015-01-25 13:55:55 -0500 362) }
0ee9608c89e81 (Daniel Borkmann 2015-11-05 00:01:51 +0100 363)
0ee9608c89e81 (Daniel Borkmann 2015-11-05 00:01:51 +0100 364) if (IS_ERR(dentry)) {
5955102c9984f (Al Viro 2016-01-22 15:40:57 -0500 365) inode_unlock(d_inode(parent));
0ee9608c89e81 (Daniel Borkmann 2015-11-05 00:01:51 +0100 366) simple_release_fs(&debugfs_mount, &debugfs_mount_count);
0ee9608c89e81 (Daniel Borkmann 2015-11-05 00:01:51 +0100 367) }
0ee9608c89e81 (Daniel Borkmann 2015-11-05 00:01:51 +0100 368)
190afd81e4a5f (Al Viro 2015-01-25 13:55:55 -0500 369) return dentry;
190afd81e4a5f (Al Viro 2015-01-25 13:55:55 -0500 370) }
190afd81e4a5f (Al Viro 2015-01-25 13:55:55 -0500 371)
5233e31191af6 (Al Viro 2015-01-25 14:39:49 -0500 372) static struct dentry *failed_creating(struct dentry *dentry)
190afd81e4a5f (Al Viro 2015-01-25 13:55:55 -0500 373) {
5955102c9984f (Al Viro 2016-01-22 15:40:57 -0500 374) inode_unlock(d_inode(dentry->d_parent));
190afd81e4a5f (Al Viro 2015-01-25 13:55:55 -0500 375) dput(dentry);
5233e31191af6 (Al Viro 2015-01-25 14:39:49 -0500 376) simple_release_fs(&debugfs_mount, &debugfs_mount_count);
ff9fb72bc0770 (Greg Kroah-Hartman 2019-01-23 11:28:14 +0100 377) return ERR_PTR(-ENOMEM);
5233e31191af6 (Al Viro 2015-01-25 14:39:49 -0500 378) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 379)
5233e31191af6 (Al Viro 2015-01-25 14:39:49 -0500 380) static struct dentry *end_creating(struct dentry *dentry)
5233e31191af6 (Al Viro 2015-01-25 14:39:49 -0500 381) {
5955102c9984f (Al Viro 2016-01-22 15:40:57 -0500 382) inode_unlock(d_inode(dentry->d_parent));
c3b1a350846a1 (Al Viro 2012-06-09 20:28:22 -0400 383) return dentry;
c3b1a350846a1 (Al Viro 2012-06-09 20:28:22 -0400 384) }
c3b1a350846a1 (Al Viro 2012-06-09 20:28:22 -0400 385)
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 386) static struct dentry *__debugfs_create_file(const char *name, umode_t mode,
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 387) struct dentry *parent, void *data,
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 388) const struct file_operations *proxy_fops,
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 389) const struct file_operations *real_fops)
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 390) {
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 391) struct dentry *dentry;
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 392) struct inode *inode;
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 393)
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 394) if (!(mode & S_IFMT))
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 395) mode |= S_IFREG;
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 396) BUG_ON(!S_ISREG(mode));
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 397) dentry = start_creating(name, parent);
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 398)
7d39bc50c47b3 (Nicolai Stange 2017-10-31 00:15:54 +0100 399) if (IS_ERR(dentry))
ff9fb72bc0770 (Greg Kroah-Hartman 2019-01-23 11:28:14 +0100 400) return dentry;
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 401)
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 402) if (!(debugfs_allow & DEBUGFS_ALLOW_API)) {
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 403) failed_creating(dentry);
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 404) return ERR_PTR(-EPERM);
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 405) }
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 406)
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 407) inode = debugfs_get_inode(dentry->d_sb);
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 408) if (unlikely(!inode)) {
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 409) pr_err("out of free dentries, can not create file '%s'\n",
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 410) name);
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 411) return failed_creating(dentry);
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 412) }
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 413)
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 414) inode->i_mode = mode;
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 415) inode->i_private = data;
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 416)
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 417) inode->i_op = &debugfs_file_inode_operations;
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 418) inode->i_fop = proxy_fops;
7d39bc50c47b3 (Nicolai Stange 2017-10-31 00:15:54 +0100 419) dentry->d_fsdata = (void *)((unsigned long)real_fops |
7d39bc50c47b3 (Nicolai Stange 2017-10-31 00:15:54 +0100 420) DEBUGFS_FSDATA_IS_REAL_FOPS_BIT);
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 421)
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 422) d_instantiate(dentry, inode);
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 423) fsnotify_create(d_inode(dentry->d_parent), dentry);
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 424) return end_creating(dentry);
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 425) }
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 426)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 427) /**
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 428) * debugfs_create_file - create a file in the debugfs filesystem
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 429) * @name: a pointer to a string containing the name of the file to create.
be030e653f1f3 (Alberto Bertogli 2009-10-31 18:26:52 -0300 430) * @mode: the permission that the file should have.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 431) * @parent: a pointer to the parent dentry for this file. This should be a
e227867f12302 (Masanari Iida 2014-02-18 22:54:36 +0900 432) * directory dentry if set. If this parameter is NULL, then the
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 433) * file will be created in the root of the debugfs filesystem.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 434) * @data: a pointer to something that the caller will want to get to later
8e18e2941c534 (Theodore Ts'o 2006-09-27 01:50:46 -0700 435) * on. The inode.i_private pointer will point to this value on
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 436) * the open() call.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 437) * @fops: a pointer to a struct file_operations that should be used for
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 438) * this file.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 439) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 440) * This is the basic "create a file" function for debugfs. It allows for a
be030e653f1f3 (Alberto Bertogli 2009-10-31 18:26:52 -0300 441) * wide range of flexibility in creating a file, or a directory (if you want
be030e653f1f3 (Alberto Bertogli 2009-10-31 18:26:52 -0300 442) * to create a directory, the debugfs_create_dir() function is
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 443) * recommended to be used instead.)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 444) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 445) * This function will return a pointer to a dentry if it succeeds. This
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 446) * pointer must be passed to the debugfs_remove() function when the file is
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 447) * to be removed (no automatic cleanup happens if your module is unloaded,
adc92dd4550ee (Daniel W. S. Almeida 2019-12-26 22:00:33 -0300 448) * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be
ff9fb72bc0770 (Greg Kroah-Hartman 2019-01-23 11:28:14 +0100 449) * returned.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 450) *
6468b3afa7bcd (Randy Dunlap 2006-07-20 08:16:42 -0700 451) * If debugfs is not enabled in the kernel, the value -%ENODEV will be
873760fbf4d1c (Cornelia Huck 2007-02-14 07:57:47 +0100 452) * returned.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 453) */
f4ae40a6a50a9 (Al Viro 2011-07-24 04:33:43 -0400 454) struct dentry *debugfs_create_file(const char *name, umode_t mode,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 455) struct dentry *parent, void *data,
99ac48f54a91d (Arjan van de Ven 2006-03-28 01:56:41 -0800 456) const struct file_operations *fops)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 457) {
680b302409cdc (Al Viro 2015-01-25 14:31:32 -0500 458)
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 459) return __debugfs_create_file(name, mode, parent, data,
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 460) fops ? &debugfs_full_proxy_file_operations :
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 461) &debugfs_noop_file_operations,
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 462) fops);
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 463) }
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 464) EXPORT_SYMBOL_GPL(debugfs_create_file);
9fd4dcece43a5 (Nicolai Stange 2016-03-22 14:11:13 +0100 465)
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 466) /**
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 467) * debugfs_create_file_unsafe - create a file in the debugfs filesystem
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 468) * @name: a pointer to a string containing the name of the file to create.
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 469) * @mode: the permission that the file should have.
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 470) * @parent: a pointer to the parent dentry for this file. This should be a
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 471) * directory dentry if set. If this parameter is NULL, then the
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 472) * file will be created in the root of the debugfs filesystem.
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 473) * @data: a pointer to something that the caller will want to get to later
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 474) * on. The inode.i_private pointer will point to this value on
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 475) * the open() call.
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 476) * @fops: a pointer to a struct file_operations that should be used for
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 477) * this file.
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 478) *
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 479) * debugfs_create_file_unsafe() is completely analogous to
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 480) * debugfs_create_file(), the only difference being that the fops
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 481) * handed it will not get protected against file removals by the
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 482) * debugfs core.
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 483) *
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 484) * It is your responsibility to protect your struct file_operation
0eeb27311f3a0 (Sergey Senozhatsky 2018-12-30 12:46:52 +0900 485) * methods against file removals by means of debugfs_file_get()
0eeb27311f3a0 (Sergey Senozhatsky 2018-12-30 12:46:52 +0900 486) * and debugfs_file_put(). ->open() is still protected by
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 487) * debugfs though.
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 488) *
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 489) * Any struct file_operations defined by means of
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 490) * DEFINE_DEBUGFS_ATTRIBUTE() is protected against file removals and
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 491) * thus, may be used here.
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 492) */
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 493) struct dentry *debugfs_create_file_unsafe(const char *name, umode_t mode,
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 494) struct dentry *parent, void *data,
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 495) const struct file_operations *fops)
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 496) {
9fd4dcece43a5 (Nicolai Stange 2016-03-22 14:11:13 +0100 497)
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 498) return __debugfs_create_file(name, mode, parent, data,
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 499) fops ? &debugfs_open_proxy_file_operations :
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 500) &debugfs_noop_file_operations,
49d200deaa680 (Nicolai Stange 2016-03-22 14:11:14 +0100 501) fops);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 502) }
c646880814903 (Nicolai Stange 2016-03-22 14:11:15 +0100 503) EXPORT_SYMBOL_GPL(debugfs_create_file_unsafe);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 504)
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 505) /**
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 506) * debugfs_create_file_size - create a file in the debugfs filesystem
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 507) * @name: a pointer to a string containing the name of the file to create.
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 508) * @mode: the permission that the file should have.
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 509) * @parent: a pointer to the parent dentry for this file. This should be a
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 510) * directory dentry if set. If this parameter is NULL, then the
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 511) * file will be created in the root of the debugfs filesystem.
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 512) * @data: a pointer to something that the caller will want to get to later
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 513) * on. The inode.i_private pointer will point to this value on
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 514) * the open() call.
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 515) * @fops: a pointer to a struct file_operations that should be used for
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 516) * this file.
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 517) * @file_size: initial file size
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 518) *
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 519) * This is the basic "create a file" function for debugfs. It allows for a
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 520) * wide range of flexibility in creating a file, or a directory (if you want
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 521) * to create a directory, the debugfs_create_dir() function is
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 522) * recommended to be used instead.)
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 523) */
526ee72dfdf74 (Greg Kroah-Hartman 2020-03-09 17:36:40 +0100 524) void debugfs_create_file_size(const char *name, umode_t mode,
526ee72dfdf74 (Greg Kroah-Hartman 2020-03-09 17:36:40 +0100 525) struct dentry *parent, void *data,
526ee72dfdf74 (Greg Kroah-Hartman 2020-03-09 17:36:40 +0100 526) const struct file_operations *fops,
526ee72dfdf74 (Greg Kroah-Hartman 2020-03-09 17:36:40 +0100 527) loff_t file_size)
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 528) {
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 529) struct dentry *de = debugfs_create_file(name, mode, parent, data, fops);
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 530)
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 531) if (de)
2b0143b5c986b (David Howells 2015-03-17 22:25:59 +0000 532) d_inode(de)->i_size = file_size;
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 533) }
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 534) EXPORT_SYMBOL_GPL(debugfs_create_file_size);
e59b4e9187bd5 (David Howells 2015-01-21 20:03:40 +0000 535)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 536) /**
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 537) * debugfs_create_dir - create a directory in the debugfs filesystem
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 538) * @name: a pointer to a string containing the name of the directory to
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 539) * create.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 540) * @parent: a pointer to the parent dentry for this file. This should be a
e227867f12302 (Masanari Iida 2014-02-18 22:54:36 +0900 541) * directory dentry if set. If this parameter is NULL, then the
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 542) * directory will be created in the root of the debugfs filesystem.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 543) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 544) * This function creates a directory in debugfs with the given name.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 545) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 546) * This function will return a pointer to a dentry if it succeeds. This
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 547) * pointer must be passed to the debugfs_remove() function when the file is
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 548) * to be removed (no automatic cleanup happens if your module is unloaded,
adc92dd4550ee (Daniel W. S. Almeida 2019-12-26 22:00:33 -0300 549) * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be
ff9fb72bc0770 (Greg Kroah-Hartman 2019-01-23 11:28:14 +0100 550) * returned.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 551) *
6468b3afa7bcd (Randy Dunlap 2006-07-20 08:16:42 -0700 552) * If debugfs is not enabled in the kernel, the value -%ENODEV will be
873760fbf4d1c (Cornelia Huck 2007-02-14 07:57:47 +0100 553) * returned.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 554) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 555) struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 556) {
ad5abd5ba8c66 (Al Viro 2015-01-25 14:02:31 -0500 557) struct dentry *dentry = start_creating(name, parent);
680b302409cdc (Al Viro 2015-01-25 14:31:32 -0500 558) struct inode *inode;
ad5abd5ba8c66 (Al Viro 2015-01-25 14:02:31 -0500 559)
ad5abd5ba8c66 (Al Viro 2015-01-25 14:02:31 -0500 560) if (IS_ERR(dentry))
ff9fb72bc0770 (Greg Kroah-Hartman 2019-01-23 11:28:14 +0100 561) return dentry;
ad5abd5ba8c66 (Al Viro 2015-01-25 14:02:31 -0500 562)
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 563) if (!(debugfs_allow & DEBUGFS_ALLOW_API)) {
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 564) failed_creating(dentry);
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 565) return ERR_PTR(-EPERM);
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 566) }
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 567)
edac65eaf8d5c (Al Viro 2015-01-25 14:36:18 -0500 568) inode = debugfs_get_inode(dentry->d_sb);
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 569) if (unlikely(!inode)) {
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 570) pr_err("out of free dentries, can not create directory '%s'\n",
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 571) name);
5233e31191af6 (Al Viro 2015-01-25 14:39:49 -0500 572) return failed_creating(dentry);
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 573) }
680b302409cdc (Al Viro 2015-01-25 14:31:32 -0500 574)
f5b7769eb0400 (Linus Torvalds 2018-06-12 20:52:16 -0700 575) inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 576) inode->i_op = &debugfs_dir_inode_operations;
edac65eaf8d5c (Al Viro 2015-01-25 14:36:18 -0500 577) inode->i_fop = &simple_dir_operations;
edac65eaf8d5c (Al Viro 2015-01-25 14:36:18 -0500 578)
edac65eaf8d5c (Al Viro 2015-01-25 14:36:18 -0500 579) /* directory inodes start off with i_nlink == 2 (for "." entry) */
edac65eaf8d5c (Al Viro 2015-01-25 14:36:18 -0500 580) inc_nlink(inode);
680b302409cdc (Al Viro 2015-01-25 14:31:32 -0500 581) d_instantiate(dentry, inode);
2b0143b5c986b (David Howells 2015-03-17 22:25:59 +0000 582) inc_nlink(d_inode(dentry->d_parent));
2b0143b5c986b (David Howells 2015-03-17 22:25:59 +0000 583) fsnotify_mkdir(d_inode(dentry->d_parent), dentry);
5233e31191af6 (Al Viro 2015-01-25 14:39:49 -0500 584) return end_creating(dentry);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 585) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 586) EXPORT_SYMBOL_GPL(debugfs_create_dir);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 587)
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 588) /**
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 589) * debugfs_create_automount - create automount point in the debugfs filesystem
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 590) * @name: a pointer to a string containing the name of the file to create.
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 591) * @parent: a pointer to the parent dentry for this file. This should be a
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 592) * directory dentry if set. If this parameter is NULL, then the
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 593) * file will be created in the root of the debugfs filesystem.
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 594) * @f: function to be called when pathname resolution steps on that one.
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 595) * @data: opaque argument to pass to f().
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 596) *
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 597) * @f should return what ->d_automount() would.
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 598) */
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 599) struct dentry *debugfs_create_automount(const char *name,
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 600) struct dentry *parent,
93faccbbfa958 (Eric W. Biederman 2017-02-01 06:06:16 +1300 601) debugfs_automount_t f,
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 602) void *data)
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 603) {
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 604) struct dentry *dentry = start_creating(name, parent);
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 605) struct inode *inode;
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 606)
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 607) if (IS_ERR(dentry))
ff9fb72bc0770 (Greg Kroah-Hartman 2019-01-23 11:28:14 +0100 608) return dentry;
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 609)
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 610) if (!(debugfs_allow & DEBUGFS_ALLOW_API)) {
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 611) failed_creating(dentry);
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 612) return ERR_PTR(-EPERM);
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 613) }
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 614)
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 615) inode = debugfs_get_inode(dentry->d_sb);
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 616) if (unlikely(!inode)) {
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 617) pr_err("out of free dentries, can not create automount '%s'\n",
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 618) name);
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 619) return failed_creating(dentry);
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 620) }
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 621)
87243deb88671 (Seth Forshee 2016-03-09 09:18:07 -0600 622) make_empty_dir_inode(inode);
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 623) inode->i_flags |= S_AUTOMOUNT;
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 624) inode->i_private = data;
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 625) dentry->d_fsdata = (void *)f;
a8f324a46fbe5 (Roman Pen 2016-02-09 11:30:29 +0100 626) /* directory inodes start off with i_nlink == 2 (for "." entry) */
a8f324a46fbe5 (Roman Pen 2016-02-09 11:30:29 +0100 627) inc_nlink(inode);
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 628) d_instantiate(dentry, inode);
a8f324a46fbe5 (Roman Pen 2016-02-09 11:30:29 +0100 629) inc_nlink(d_inode(dentry->d_parent));
a8f324a46fbe5 (Roman Pen 2016-02-09 11:30:29 +0100 630) fsnotify_mkdir(d_inode(dentry->d_parent), dentry);
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 631) return end_creating(dentry);
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 632) }
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 633) EXPORT_SYMBOL(debugfs_create_automount);
77b3da6e3232d (Al Viro 2015-01-25 15:10:32 -0500 634)
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 635) /**
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 636) * debugfs_create_symlink- create a symbolic link in the debugfs filesystem
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 637) * @name: a pointer to a string containing the name of the symbolic link to
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 638) * create.
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 639) * @parent: a pointer to the parent dentry for this symbolic link. This
e227867f12302 (Masanari Iida 2014-02-18 22:54:36 +0900 640) * should be a directory dentry if set. If this parameter is NULL,
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 641) * then the symbolic link will be created in the root of the debugfs
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 642) * filesystem.
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 643) * @target: a pointer to a string containing the path to the target of the
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 644) * symbolic link.
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 645) *
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 646) * This function creates a symbolic link with the given name in debugfs that
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 647) * links to the given target path.
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 648) *
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 649) * This function will return a pointer to a dentry if it succeeds. This
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 650) * pointer must be passed to the debugfs_remove() function when the symbolic
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 651) * link is to be removed (no automatic cleanup happens if your module is
adc92dd4550ee (Daniel W. S. Almeida 2019-12-26 22:00:33 -0300 652) * unloaded, you are responsible here.) If an error occurs, ERR_PTR(-ERROR)
ff9fb72bc0770 (Greg Kroah-Hartman 2019-01-23 11:28:14 +0100 653) * will be returned.
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 654) *
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 655) * If debugfs is not enabled in the kernel, the value -%ENODEV will be
873760fbf4d1c (Cornelia Huck 2007-02-14 07:57:47 +0100 656) * returned.
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 657) */
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 658) struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 659) const char *target)
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 660) {
ad5abd5ba8c66 (Al Viro 2015-01-25 14:02:31 -0500 661) struct dentry *dentry;
680b302409cdc (Al Viro 2015-01-25 14:31:32 -0500 662) struct inode *inode;
680b302409cdc (Al Viro 2015-01-25 14:31:32 -0500 663) char *link = kstrdup(target, GFP_KERNEL);
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 664) if (!link)
ff9fb72bc0770 (Greg Kroah-Hartman 2019-01-23 11:28:14 +0100 665) return ERR_PTR(-ENOMEM);
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 666)
ad5abd5ba8c66 (Al Viro 2015-01-25 14:02:31 -0500 667) dentry = start_creating(name, parent);
ad5abd5ba8c66 (Al Viro 2015-01-25 14:02:31 -0500 668) if (IS_ERR(dentry)) {
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 669) kfree(link);
ff9fb72bc0770 (Greg Kroah-Hartman 2019-01-23 11:28:14 +0100 670) return dentry;
ad5abd5ba8c66 (Al Viro 2015-01-25 14:02:31 -0500 671) }
ad5abd5ba8c66 (Al Viro 2015-01-25 14:02:31 -0500 672)
edac65eaf8d5c (Al Viro 2015-01-25 14:36:18 -0500 673) inode = debugfs_get_inode(dentry->d_sb);
680b302409cdc (Al Viro 2015-01-25 14:31:32 -0500 674) if (unlikely(!inode)) {
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 675) pr_err("out of free dentries, can not create symlink '%s'\n",
43e23b6c0b015 (Greg Kroah-Hartman 2019-07-03 09:16:53 +0200 676) name);
ad5abd5ba8c66 (Al Viro 2015-01-25 14:02:31 -0500 677) kfree(link);
5233e31191af6 (Al Viro 2015-01-25 14:39:49 -0500 678) return failed_creating(dentry);
680b302409cdc (Al Viro 2015-01-25 14:31:32 -0500 679) }
edac65eaf8d5c (Al Viro 2015-01-25 14:36:18 -0500 680) inode->i_mode = S_IFLNK | S_IRWXUGO;
5496197f9b084 (David Howells 2019-08-19 17:18:02 -0700 681) inode->i_op = &debugfs_symlink_inode_operations;
5723cb01f0295 (Al Viro 2015-05-02 10:27:18 -0400 682) inode->i_link = link;
680b302409cdc (Al Viro 2015-01-25 14:31:32 -0500 683) d_instantiate(dentry, inode);
5233e31191af6 (Al Viro 2015-01-25 14:39:49 -0500 684) return end_creating(dentry);
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 685) }
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 686) EXPORT_SYMBOL_GPL(debugfs_create_symlink);
66f5496393dcc (Peter Oberparleiter 2007-02-13 12:13:54 +0100 687)
823e545c02779 (Amir Goldstein 2019-05-26 17:34:07 +0300 688) static void __debugfs_file_removed(struct dentry *dentry)
e9117a5a4bf65 (Nicolai Stange 2017-10-31 00:15:48 +0100 689) {
e9117a5a4bf65 (Nicolai Stange 2017-10-31 00:15:48 +0100 690) struct debugfs_fsdata *fsd;
e9117a5a4bf65 (Nicolai Stange 2017-10-31 00:15:48 +0100 691)
7d39bc50c47b3 (Nicolai Stange 2017-10-31 00:15:54 +0100 692) /*
7d39bc50c47b3 (Nicolai Stange 2017-10-31 00:15:54 +0100 693) * Paired with the closing smp_mb() implied by a successful
7d39bc50c47b3 (Nicolai Stange 2017-10-31 00:15:54 +0100 694) * cmpxchg() in debugfs_file_get(): either
7d39bc50c47b3 (Nicolai Stange 2017-10-31 00:15:54 +0100 695) * debugfs_file_get() must see a dead dentry or we must see a
7d39bc50c47b3 (Nicolai Stange 2017-10-31 00:15:54 +0100 696) * debugfs_fsdata instance at ->d_fsdata here (or both).
7d39bc50c47b3 (Nicolai Stange 2017-10-31 00:15:54 +0100 697) */
7d39bc50c47b3 (Nicolai Stange 2017-10-31 00:15:54 +0100 698) smp_mb();
7d39bc50c47b3 (Nicolai Stange 2017-10-31 00:15:54 +0100 699) fsd = READ_ONCE(dentry->d_fsdata);
7d39bc50c47b3 (Nicolai Stange 2017-10-31 00:15:54 +0100 700) if ((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT)
7d39bc50c47b3 (Nicolai Stange 2017-10-31 00:15:54 +0100 701) return;
e9117a5a4bf65 (Nicolai Stange 2017-10-31 00:15:48 +0100 702) if (!refcount_dec_and_test(&fsd->active_users))
e9117a5a4bf65 (Nicolai Stange 2017-10-31 00:15:48 +0100 703) wait_for_completion(&fsd->active_users_drained);
e9117a5a4bf65 (Nicolai Stange 2017-10-31 00:15:48 +0100 704) }
e9117a5a4bf65 (Nicolai Stange 2017-10-31 00:15:48 +0100 705)
a3d1e7eb5abe3 (Al Viro 2019-11-18 09:43:10 -0500 706) static void remove_one(struct dentry *victim)
9505e6375640f (Haavard Skinnemoen 2008-07-01 15:14:51 +0200 707) {
a3d1e7eb5abe3 (Al Viro 2019-11-18 09:43:10 -0500 708) if (d_is_reg(victim))
a3d1e7eb5abe3 (Al Viro 2019-11-18 09:43:10 -0500 709) __debugfs_file_removed(victim);
a3d1e7eb5abe3 (Al Viro 2019-11-18 09:43:10 -0500 710) simple_release_fs(&debugfs_mount, &debugfs_mount_count);
9505e6375640f (Haavard Skinnemoen 2008-07-01 15:14:51 +0200 711) }
9505e6375640f (Haavard Skinnemoen 2008-07-01 15:14:51 +0200 712)
9505e6375640f (Haavard Skinnemoen 2008-07-01 15:14:51 +0200 713) /**
a3d1e7eb5abe3 (Al Viro 2019-11-18 09:43:10 -0500 714) * debugfs_remove - recursively removes a directory
398dc4ad52022 (Ulf Magnusson 2015-09-07 19:03:15 +0200 715) * @dentry: a pointer to a the dentry of the directory to be removed. If this
398dc4ad52022 (Ulf Magnusson 2015-09-07 19:03:15 +0200 716) * parameter is NULL or an error value, nothing will be done.
9505e6375640f (Haavard Skinnemoen 2008-07-01 15:14:51 +0200 717) *
9505e6375640f (Haavard Skinnemoen 2008-07-01 15:14:51 +0200 718) * This function recursively removes a directory tree in debugfs that
9505e6375640f (Haavard Skinnemoen 2008-07-01 15:14:51 +0200 719) * was previously created with a call to another debugfs function
9505e6375640f (Haavard Skinnemoen 2008-07-01 15:14:51 +0200 720) * (like debugfs_create_file() or variants thereof.)
9505e6375640f (Haavard Skinnemoen 2008-07-01 15:14:51 +0200 721) *
9505e6375640f (Haavard Skinnemoen 2008-07-01 15:14:51 +0200 722) * This function is required to be called in order for the file to be
9505e6375640f (Haavard Skinnemoen 2008-07-01 15:14:51 +0200 723) * removed, no automatic cleanup of files will happen when a module is
9505e6375640f (Haavard Skinnemoen 2008-07-01 15:14:51 +0200 724) * removed, you are responsible here.
9505e6375640f (Haavard Skinnemoen 2008-07-01 15:14:51 +0200 725) */
a3d1e7eb5abe3 (Al Viro 2019-11-18 09:43:10 -0500 726) void debugfs_remove(struct dentry *dentry)
9505e6375640f (Haavard Skinnemoen 2008-07-01 15:14:51 +0200 727) {
a59d6293e5372 (Arend van Spriel 2012-05-23 15:13:07 +0200 728) if (IS_ERR_OR_NULL(dentry))
9505e6375640f (Haavard Skinnemoen 2008-07-01 15:14:51 +0200 729) return;
9505e6375640f (Haavard Skinnemoen 2008-07-01 15:14:51 +0200 730)
a3d1e7eb5abe3 (Al Viro 2019-11-18 09:43:10 -0500 731) simple_pin_fs(&debug_fs_type, &debugfs_mount, &debugfs_mount_count);
a3d1e7eb5abe3 (Al Viro 2019-11-18 09:43:10 -0500 732) simple_recursive_removal(dentry, remove_one);
a3d1e7eb5abe3 (Al Viro 2019-11-18 09:43:10 -0500 733) simple_release_fs(&debugfs_mount, &debugfs_mount_count);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 734) }
a3d1e7eb5abe3 (Al Viro 2019-11-18 09:43:10 -0500 735) EXPORT_SYMBOL_GPL(debugfs_remove);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 736)
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 737) /**
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 738) * debugfs_rename - rename a file/directory in the debugfs filesystem
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 739) * @old_dir: a pointer to the parent dentry for the renamed object. This
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 740) * should be a directory dentry.
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 741) * @old_dentry: dentry of an object to be renamed.
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 742) * @new_dir: a pointer to the parent dentry where the object should be
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 743) * moved. This should be a directory dentry.
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 744) * @new_name: a pointer to a string containing the target name.
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 745) *
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 746) * This function renames a file/directory in debugfs. The target must not
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 747) * exist for rename to succeed.
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 748) *
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 749) * This function will return a pointer to old_dentry (which is updated to
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 750) * reflect renaming) if it succeeds. If an error occurs, %NULL will be
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 751) * returned.
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 752) *
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 753) * If debugfs is not enabled in the kernel, the value -%ENODEV will be
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 754) * returned.
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 755) */
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 756) struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 757) struct dentry *new_dir, const char *new_name)
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 758) {
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 759) int error;
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 760) struct dentry *dentry = NULL, *trap;
49d31c2f389ac (Al Viro 2017-07-07 14:51:19 -0400 761) struct name_snapshot old_name;
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 762)
d88c93f090f70 (Greg Kroah-Hartman 2019-01-23 11:27:02 +0100 763) if (IS_ERR(old_dir))
d88c93f090f70 (Greg Kroah-Hartman 2019-01-23 11:27:02 +0100 764) return old_dir;
d88c93f090f70 (Greg Kroah-Hartman 2019-01-23 11:27:02 +0100 765) if (IS_ERR(new_dir))
d88c93f090f70 (Greg Kroah-Hartman 2019-01-23 11:27:02 +0100 766) return new_dir;
d88c93f090f70 (Greg Kroah-Hartman 2019-01-23 11:27:02 +0100 767) if (IS_ERR_OR_NULL(old_dentry))
d88c93f090f70 (Greg Kroah-Hartman 2019-01-23 11:27:02 +0100 768) return old_dentry;
d88c93f090f70 (Greg Kroah-Hartman 2019-01-23 11:27:02 +0100 769)
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 770) trap = lock_rename(new_dir, old_dir);
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 771) /* Source or destination directories don't exist? */
2b0143b5c986b (David Howells 2015-03-17 22:25:59 +0000 772) if (d_really_is_negative(old_dir) || d_really_is_negative(new_dir))
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 773) goto exit;
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 774) /* Source does not exist, cyclic rename, or mountpoint? */
2b0143b5c986b (David Howells 2015-03-17 22:25:59 +0000 775) if (d_really_is_negative(old_dentry) || old_dentry == trap ||
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 776) d_mountpoint(old_dentry))
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 777) goto exit;
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 778) dentry = lookup_one_len(new_name, new_dir, strlen(new_name));
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 779) /* Lookup failed, cyclic rename or target exists? */
2b0143b5c986b (David Howells 2015-03-17 22:25:59 +0000 780) if (IS_ERR(dentry) || dentry == trap || d_really_is_positive(dentry))
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 781) goto exit;
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 782)
49d31c2f389ac (Al Viro 2017-07-07 14:51:19 -0400 783) take_dentry_name_snapshot(&old_name, old_dentry);
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 784)
549c7297717c3 (Christian Brauner 2021-01-21 14:19:43 +0100 785) error = simple_rename(&init_user_ns, d_inode(old_dir), old_dentry,
549c7297717c3 (Christian Brauner 2021-01-21 14:19:43 +0100 786) d_inode(new_dir), dentry, 0);
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 787) if (error) {
49d31c2f389ac (Al Viro 2017-07-07 14:51:19 -0400 788) release_dentry_name_snapshot(&old_name);
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 789) goto exit;
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 790) }
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 791) d_move(old_dentry, dentry);
f4ec3a3d43bcd (Al Viro 2019-04-26 13:21:24 -0400 792) fsnotify_move(d_inode(old_dir), d_inode(new_dir), &old_name.name,
e36cb0b89ce20 (David Howells 2015-01-29 12:02:35 +0000 793) d_is_dir(old_dentry),
5a190ae69766d (Al Viro 2007-06-07 12:19:32 -0400 794) NULL, old_dentry);
49d31c2f389ac (Al Viro 2017-07-07 14:51:19 -0400 795) release_dentry_name_snapshot(&old_name);
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 796) unlock_rename(new_dir, old_dir);
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 797) dput(dentry);
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 798) return old_dentry;
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 799) exit:
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 800) if (dentry && !IS_ERR(dentry))
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 801) dput(dentry);
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 802) unlock_rename(new_dir, old_dir);
ff9fb72bc0770 (Greg Kroah-Hartman 2019-01-23 11:28:14 +0100 803) if (IS_ERR(dentry))
ff9fb72bc0770 (Greg Kroah-Hartman 2019-01-23 11:28:14 +0100 804) return dentry;
ff9fb72bc0770 (Greg Kroah-Hartman 2019-01-23 11:28:14 +0100 805) return ERR_PTR(-EINVAL);
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 806) }
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 807) EXPORT_SYMBOL_GPL(debugfs_rename);
cfc94cdf8e0f1 (Jan Kara 2007-05-09 13:19:52 +0200 808)
c0f92ba99bdea (Frederic Weisbecker 2009-03-22 23:10:44 +0100 809) /**
c0f92ba99bdea (Frederic Weisbecker 2009-03-22 23:10:44 +0100 810) * debugfs_initialized - Tells whether debugfs has been registered
c0f92ba99bdea (Frederic Weisbecker 2009-03-22 23:10:44 +0100 811) */
c0f92ba99bdea (Frederic Weisbecker 2009-03-22 23:10:44 +0100 812) bool debugfs_initialized(void)
c0f92ba99bdea (Frederic Weisbecker 2009-03-22 23:10:44 +0100 813) {
c0f92ba99bdea (Frederic Weisbecker 2009-03-22 23:10:44 +0100 814) return debugfs_registered;
c0f92ba99bdea (Frederic Weisbecker 2009-03-22 23:10:44 +0100 815) }
c0f92ba99bdea (Frederic Weisbecker 2009-03-22 23:10:44 +0100 816) EXPORT_SYMBOL_GPL(debugfs_initialized);
c0f92ba99bdea (Frederic Weisbecker 2009-03-22 23:10:44 +0100 817)
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 818) static int __init debugfs_kernel(char *str)
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 819) {
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 820) if (str) {
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 821) if (!strcmp(str, "on"))
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 822) debugfs_allow = DEBUGFS_ALLOW_API | DEBUGFS_ALLOW_MOUNT;
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 823) else if (!strcmp(str, "no-mount"))
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 824) debugfs_allow = DEBUGFS_ALLOW_API;
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 825) else if (!strcmp(str, "off"))
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 826) debugfs_allow = 0;
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 827) }
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 828)
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 829) return 0;
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 830) }
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 831) early_param("debugfs", debugfs_kernel);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 832) static int __init debugfs_init(void)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 833) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 834) int retval;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 835)
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 836) if (!(debugfs_allow & DEBUGFS_ALLOW_MOUNT))
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 837) return -EPERM;
a24c6f7bc923d (Peter Enderborg 2020-07-16 09:15:11 +0200 838)
f9bb48825a6b5 (Eric W. Biederman 2015-05-13 17:35:41 -0500 839) retval = sysfs_create_mount_point(kernel_kobj, "debug");
f9bb48825a6b5 (Eric W. Biederman 2015-05-13 17:35:41 -0500 840) if (retval)
f9bb48825a6b5 (Eric W. Biederman 2015-05-13 17:35:41 -0500 841) return retval;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 842)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 843) retval = register_filesystem(&debug_fs_type);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 844) if (retval)
f9bb48825a6b5 (Eric W. Biederman 2015-05-13 17:35:41 -0500 845) sysfs_remove_mount_point(kernel_kobj, "debug");
c0f92ba99bdea (Frederic Weisbecker 2009-03-22 23:10:44 +0100 846) else
c0f92ba99bdea (Frederic Weisbecker 2009-03-22 23:10:44 +0100 847) debugfs_registered = true;
c0f92ba99bdea (Frederic Weisbecker 2009-03-22 23:10:44 +0100 848)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 849) return retval;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 850) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 851) core_initcall(debugfs_init);