xref: /OK3568_Linux_fs/kernel/arch/s390/hypfs/hypfs_dbfs.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Hypervisor filesystem for Linux on s390 - debugfs interface
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright IBM Corp. 2010
6*4882a593Smuzhiyun  * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/slab.h>
10*4882a593Smuzhiyun #include "hypfs.h"
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun static struct dentry *dbfs_dir;
13*4882a593Smuzhiyun 
hypfs_dbfs_data_alloc(struct hypfs_dbfs_file * f)14*4882a593Smuzhiyun static struct hypfs_dbfs_data *hypfs_dbfs_data_alloc(struct hypfs_dbfs_file *f)
15*4882a593Smuzhiyun {
16*4882a593Smuzhiyun 	struct hypfs_dbfs_data *data;
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun 	data = kmalloc(sizeof(*data), GFP_KERNEL);
19*4882a593Smuzhiyun 	if (!data)
20*4882a593Smuzhiyun 		return NULL;
21*4882a593Smuzhiyun 	data->dbfs_file = f;
22*4882a593Smuzhiyun 	return data;
23*4882a593Smuzhiyun }
24*4882a593Smuzhiyun 
hypfs_dbfs_data_free(struct hypfs_dbfs_data * data)25*4882a593Smuzhiyun static void hypfs_dbfs_data_free(struct hypfs_dbfs_data *data)
26*4882a593Smuzhiyun {
27*4882a593Smuzhiyun 	data->dbfs_file->data_free(data->buf_free_ptr);
28*4882a593Smuzhiyun 	kfree(data);
29*4882a593Smuzhiyun }
30*4882a593Smuzhiyun 
dbfs_read(struct file * file,char __user * buf,size_t size,loff_t * ppos)31*4882a593Smuzhiyun static ssize_t dbfs_read(struct file *file, char __user *buf,
32*4882a593Smuzhiyun 			 size_t size, loff_t *ppos)
33*4882a593Smuzhiyun {
34*4882a593Smuzhiyun 	struct hypfs_dbfs_data *data;
35*4882a593Smuzhiyun 	struct hypfs_dbfs_file *df;
36*4882a593Smuzhiyun 	ssize_t rc;
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 	if (*ppos != 0)
39*4882a593Smuzhiyun 		return 0;
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun 	df = file_inode(file)->i_private;
42*4882a593Smuzhiyun 	mutex_lock(&df->lock);
43*4882a593Smuzhiyun 	data = hypfs_dbfs_data_alloc(df);
44*4882a593Smuzhiyun 	if (!data) {
45*4882a593Smuzhiyun 		mutex_unlock(&df->lock);
46*4882a593Smuzhiyun 		return -ENOMEM;
47*4882a593Smuzhiyun 	}
48*4882a593Smuzhiyun 	rc = df->data_create(&data->buf, &data->buf_free_ptr, &data->size);
49*4882a593Smuzhiyun 	if (rc) {
50*4882a593Smuzhiyun 		mutex_unlock(&df->lock);
51*4882a593Smuzhiyun 		kfree(data);
52*4882a593Smuzhiyun 		return rc;
53*4882a593Smuzhiyun 	}
54*4882a593Smuzhiyun 	mutex_unlock(&df->lock);
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	rc = simple_read_from_buffer(buf, size, ppos, data->buf, data->size);
57*4882a593Smuzhiyun 	hypfs_dbfs_data_free(data);
58*4882a593Smuzhiyun 	return rc;
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun 
dbfs_ioctl(struct file * file,unsigned int cmd,unsigned long arg)61*4882a593Smuzhiyun static long dbfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun 	struct hypfs_dbfs_file *df = file_inode(file)->i_private;
64*4882a593Smuzhiyun 	long rc;
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	mutex_lock(&df->lock);
67*4882a593Smuzhiyun 	if (df->unlocked_ioctl)
68*4882a593Smuzhiyun 		rc = df->unlocked_ioctl(file, cmd, arg);
69*4882a593Smuzhiyun 	else
70*4882a593Smuzhiyun 		rc = -ENOTTY;
71*4882a593Smuzhiyun 	mutex_unlock(&df->lock);
72*4882a593Smuzhiyun 	return rc;
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun static const struct file_operations dbfs_ops = {
76*4882a593Smuzhiyun 	.read		= dbfs_read,
77*4882a593Smuzhiyun 	.llseek		= no_llseek,
78*4882a593Smuzhiyun 	.unlocked_ioctl = dbfs_ioctl,
79*4882a593Smuzhiyun };
80*4882a593Smuzhiyun 
hypfs_dbfs_create_file(struct hypfs_dbfs_file * df)81*4882a593Smuzhiyun void hypfs_dbfs_create_file(struct hypfs_dbfs_file *df)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun 	df->dentry = debugfs_create_file(df->name, 0400, dbfs_dir, df,
84*4882a593Smuzhiyun 					 &dbfs_ops);
85*4882a593Smuzhiyun 	mutex_init(&df->lock);
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun 
hypfs_dbfs_remove_file(struct hypfs_dbfs_file * df)88*4882a593Smuzhiyun void hypfs_dbfs_remove_file(struct hypfs_dbfs_file *df)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun 	debugfs_remove(df->dentry);
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun 
hypfs_dbfs_init(void)93*4882a593Smuzhiyun void hypfs_dbfs_init(void)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun 	dbfs_dir = debugfs_create_dir("s390_hypfs", NULL);
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun 
hypfs_dbfs_exit(void)98*4882a593Smuzhiyun void hypfs_dbfs_exit(void)
99*4882a593Smuzhiyun {
100*4882a593Smuzhiyun 	debugfs_remove(dbfs_dir);
101*4882a593Smuzhiyun }
102