VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
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);