debugfs中私有数据的使用

#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/wait.h>
#include <linux/dcache.h>

struct dentry *test_dentry;

struct PrivateInfo {
	int id;
	char tmp[20];
};

static struct PrivateInfo info = {
	.id = 25,
	.tmp = "hello world",
};

int demo_open(struct inode *inode, struct file *file)
{
	struct PrivateInfo *pInfo;

	pr_info("%s, ===>\n", __func__);
	file->private_data = inode->i_private;
	if (IS_ERR_OR_NULL(file->private_data)) {
		pr_err("%s, file->private_data invalid\n", __func__);
		return -EFAULT;
	}

	pInfo = (struct PrivateInfo*)(file->private_data);

	pr_info("%s, id %d, tmp %s\n", __func__, pInfo->id, pInfo->tmp);
	pr_info("%s, <===\n", __func__);
	return 0;
}

int demo_release(struct inode *inode, struct file *file)
{
	struct PrivateInfo *pInfo;

	pr_info("%s, ===>\n", __func__);
	file->private_data = inode->i_private;
	if (IS_ERR_OR_NULL(file->private_data)) {
		pr_err("%s, file->private_data invalid\n", __func__);
		return -EFAULT;
	}

	pInfo = (struct PrivateInfo*)(file->private_data);

	pr_info("%s, id %d, tmp %s\n", __func__, pInfo->id, pInfo->tmp);
	pr_info("%s, <===\n", __func__);
	return 0;
}

static const struct file_operations demo_fops = {
	.open  = demo_open,
	.release  = demo_release,
};

static int __init my_demo_init(void)
{
	pr_info("%s, ===>\n", __func__);
	pr_info("%s, before debugfs create file\n", __func__);
	// 这里一定是 (void *)&info
	test_dentry = (struct dentry *)debugfs_create_file("debug_demo", 0666, NULL, (void *)&info, &demo_fops);
	if (IS_ERR_OR_NULL(test_dentry)) {
		pr_err("%s, debugfs create file failed\n", __func__);
	} else {
		pr_info("%s, debugfs create file success\n", __func__);
	}
	pr_info("%s, <===\n", __func__);
	return 0;
}

static void my_demo_exit(void)
{
	pr_info("%s, ===>\n", __func__);
	if (IS_ERR_OR_NULL(test_dentry)) {
		pr_err("%s, debugfs is invalid\n", __func__);
	} else {
		debugfs_remove(test_dentry);
		test_dentry = NULL;
		pr_info("%s, debugfs remove success\n", __func__);
	}
	pr_info("%s, <===\n", __func__);
}

module_init(my_demo_init);
module_exit(my_demo_exit);

MODULE_LICENSE ("GPL");
MODULE_AUTHOR ("kiss1994");
MODULE_DESCRIPTION ("debugfs");
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main() {
	char *filename = "/sys/kernel/debug/debug_demo";
	int fd = open(filename,O_RDWR);
	if(fd<0){
		perror("open fail \n");
		return -1;
	}
	printf("open file %s success!\n", filename);
	sleep(3);
	close(fd);
	printf("close file %s success!\n", filename);
	return 0;
}
[ 4215.441563] my_demo_init, ===>
[ 4215.441568] my_demo_init, before debugfs create file
[ 4215.441595] my_demo_init, debugfs create file success
[ 4215.441596] my_demo_init, <===

[ 4471.569330] demo_open, ===>
[ 4471.569338] demo_open, id 25, tmp hello world
[ 4471.569340] demo_open, <===

[ 4474.570193] demo_release, ===>
[ 4474.570202] demo_release, id 25, tmp hello world
[ 4474.570204] demo_release, <===

[ 4489.417556] my_demo_exit, ===>
[ 4489.417725] my_demo_exit, debugfs remove success
[ 4489.417728] my_demo_exit, <===

//=======================================================

/**
 * debugfs_create_file - create a file in the debugfs filesystem
 * @name: a pointer to a string containing the name of the file to create.
 * @mode: the permission that the file should have.
 * @parent: a pointer to the parent dentry for this file.  This should be a
 *          directory dentry if set.  If this parameter is NULL, then the
 *          file will be created in the root of the debugfs filesystem.
 * @data: a pointer to something that the caller will want to get to later
 *        on.  The inode.i_private pointer will point to this value on
 *        the open() call.
 * @fops: a pointer to a struct file_operations that should be used for
 *        this file.
 *
 * This is the basic "create a file" function for debugfs.  It allows for a
 * wide range of flexibility in creating a file, or a directory (if you want
 * to create a directory, the debugfs_create_dir() function is
 * recommended to be used instead.)
 *
 * This function will return a pointer to a dentry if it succeeds.  This
 * pointer must be passed to the debugfs_remove() function when the file is
 * to be removed (no automatic cleanup happens if your module is unloaded,
 * you are responsible here.)  If an error occurs, ERR_PTR(-ERROR) will be
 * returned.
 *
 * If debugfs is not enabled in the kernel, the value -%ENODEV will be
 * returned.
 */
struct dentry *debugfs_create_file(const char *name, umode_t mode,
				   struct dentry *parent, void *data,
				   const struct file_operations *fops)
{

	return __debugfs_create_file(name, mode, parent, data,
				fops ? &debugfs_full_proxy_file_operations :
					&debugfs_noop_file_operations,
				fops);
}
EXPORT_SYMBOL_GPL(debugfs_create_file);
/**
 * debugfs_remove - recursively removes a directory
 * @dentry: a pointer to a the dentry of the directory to be removed.  If this
 *          parameter is NULL or an error value, nothing will be done.
 *
 * This function recursively removes a directory tree in debugfs that
 * was previously created with a call to another debugfs function
 * (like debugfs_create_file() or variants thereof.)
 *
 * This function is required to be called in order for the file to be
 * removed, no automatic cleanup of files will happen when a module is
 * removed, you are responsible here.
 */
void debugfs_remove(struct dentry *dentry)
{
	if (IS_ERR_OR_NULL(dentry))
		return;

	simple_pin_fs(&debug_fs_type, &debugfs_mount, &debugfs_mount_count);
	simple_recursive_removal(dentry, remove_one);
	simple_release_fs(&debugfs_mount, &debugfs_mount_count);
}
EXPORT_SYMBOL_GPL(debugfs_remove);

Guess you like

Origin blog.csdn.net/wangkai6666/article/details/121623389