Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/s390/hypfs/hypfs_dbfs.c
26424 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* Hypervisor filesystem for Linux on s390 - debugfs interface
4
*
5
* Copyright IBM Corp. 2010
6
* Author(s): Michael Holzheu <[email protected]>
7
*/
8
9
#include <linux/security.h>
10
#include <linux/slab.h>
11
#include "hypfs.h"
12
13
static struct dentry *dbfs_dir;
14
15
static struct hypfs_dbfs_data *hypfs_dbfs_data_alloc(struct hypfs_dbfs_file *f)
16
{
17
struct hypfs_dbfs_data *data;
18
19
data = kmalloc(sizeof(*data), GFP_KERNEL);
20
if (!data)
21
return NULL;
22
data->dbfs_file = f;
23
return data;
24
}
25
26
static void hypfs_dbfs_data_free(struct hypfs_dbfs_data *data)
27
{
28
data->dbfs_file->data_free(data->buf_free_ptr);
29
kfree(data);
30
}
31
32
static ssize_t dbfs_read(struct file *file, char __user *buf,
33
size_t size, loff_t *ppos)
34
{
35
struct hypfs_dbfs_data *data;
36
struct hypfs_dbfs_file *df;
37
ssize_t rc;
38
39
if (*ppos != 0)
40
return 0;
41
42
df = file_inode(file)->i_private;
43
if (mutex_lock_interruptible(&df->lock))
44
return -ERESTARTSYS;
45
46
data = hypfs_dbfs_data_alloc(df);
47
if (!data) {
48
mutex_unlock(&df->lock);
49
return -ENOMEM;
50
}
51
rc = df->data_create(&data->buf, &data->buf_free_ptr, &data->size);
52
if (rc) {
53
mutex_unlock(&df->lock);
54
kfree(data);
55
return rc;
56
}
57
mutex_unlock(&df->lock);
58
59
rc = simple_read_from_buffer(buf, size, ppos, data->buf, data->size);
60
hypfs_dbfs_data_free(data);
61
return rc;
62
}
63
64
static long dbfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
65
{
66
struct hypfs_dbfs_file *df = file_inode(file)->i_private;
67
long rc;
68
69
mutex_lock(&df->lock);
70
rc = df->unlocked_ioctl(file, cmd, arg);
71
mutex_unlock(&df->lock);
72
return rc;
73
}
74
75
static const struct file_operations dbfs_ops_ioctl = {
76
.read = dbfs_read,
77
.unlocked_ioctl = dbfs_ioctl,
78
};
79
80
static const struct file_operations dbfs_ops = {
81
.read = dbfs_read,
82
};
83
84
void hypfs_dbfs_create_file(struct hypfs_dbfs_file *df)
85
{
86
const struct file_operations *fops = &dbfs_ops;
87
88
if (df->unlocked_ioctl && !security_locked_down(LOCKDOWN_DEBUGFS))
89
fops = &dbfs_ops_ioctl;
90
df->dentry = debugfs_create_file(df->name, 0400, dbfs_dir, df, fops);
91
mutex_init(&df->lock);
92
}
93
94
void hypfs_dbfs_remove_file(struct hypfs_dbfs_file *df)
95
{
96
debugfs_remove(df->dentry);
97
}
98
99
static int __init hypfs_dbfs_init(void)
100
{
101
int rc = -ENODATA;
102
103
dbfs_dir = debugfs_create_dir("s390_hypfs", NULL);
104
if (hypfs_diag_init())
105
goto fail_dbfs_exit;
106
if (hypfs_vm_init())
107
goto fail_hypfs_diag_exit;
108
hypfs_sprp_init();
109
if (hypfs_diag0c_init())
110
goto fail_hypfs_sprp_exit;
111
rc = hypfs_fs_init();
112
if (rc)
113
goto fail_hypfs_diag0c_exit;
114
return 0;
115
116
fail_hypfs_diag0c_exit:
117
hypfs_diag0c_exit();
118
fail_hypfs_sprp_exit:
119
hypfs_sprp_exit();
120
hypfs_vm_exit();
121
fail_hypfs_diag_exit:
122
hypfs_diag_exit();
123
pr_err("Initialization of hypfs failed with rc=%i\n", rc);
124
fail_dbfs_exit:
125
debugfs_remove(dbfs_dir);
126
return rc;
127
}
128
device_initcall(hypfs_dbfs_init)
129
130