blob: 752f6df3e6974a823e9bcbdb044d3e5381d9bb4e [file] [log] [blame]
Michael Holzheu2fcb3682011-01-05 12:47:43 +01001/*
2 * Hypervisor filesystem for Linux on s390 - debugfs interface
3 *
Heiko Carstensa53c8fa2012-07-20 11:15:04 +02004 * Copyright IBM Corp. 2010
Michael Holzheu2fcb3682011-01-05 12:47:43 +01005 * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
6 */
7
8#include <linux/slab.h>
9#include "hypfs.h"
10
11static struct dentry *dbfs_dir;
12
13static struct hypfs_dbfs_data *hypfs_dbfs_data_alloc(struct hypfs_dbfs_file *f)
14{
15 struct hypfs_dbfs_data *data;
16
17 data = kmalloc(sizeof(*data), GFP_KERNEL);
18 if (!data)
19 return NULL;
Michael Holzheu2fcb3682011-01-05 12:47:43 +010020 data->dbfs_file = f;
21 return data;
22}
23
Michael Holzheua1782202015-02-09 14:49:32 +010024static void hypfs_dbfs_data_free(struct hypfs_dbfs_data *data)
Michael Holzheu2fcb3682011-01-05 12:47:43 +010025{
Michael Holzheu2fcb3682011-01-05 12:47:43 +010026 data->dbfs_file->data_free(data->buf_free_ptr);
27 kfree(data);
28}
29
Michael Holzheu2fcb3682011-01-05 12:47:43 +010030static ssize_t dbfs_read(struct file *file, char __user *buf,
31 size_t size, loff_t *ppos)
32{
33 struct hypfs_dbfs_data *data;
34 struct hypfs_dbfs_file *df;
35 ssize_t rc;
36
37 if (*ppos != 0)
38 return 0;
39
Al Viro496ad9a2013-01-23 17:07:38 -050040 df = file_inode(file)->i_private;
Michael Holzheu2fcb3682011-01-05 12:47:43 +010041 mutex_lock(&df->lock);
Michael Holzheua1782202015-02-09 14:49:32 +010042 data = hypfs_dbfs_data_alloc(df);
43 if (!data) {
44 mutex_unlock(&df->lock);
45 return -ENOMEM;
Michael Holzheu2fcb3682011-01-05 12:47:43 +010046 }
Michael Holzheua1782202015-02-09 14:49:32 +010047 rc = df->data_create(&data->buf, &data->buf_free_ptr, &data->size);
48 if (rc) {
49 mutex_unlock(&df->lock);
50 kfree(data);
51 return rc;
52 }
Michael Holzheu2fcb3682011-01-05 12:47:43 +010053 mutex_unlock(&df->lock);
54
55 rc = simple_read_from_buffer(buf, size, ppos, data->buf, data->size);
Michael Holzheua1782202015-02-09 14:49:32 +010056 hypfs_dbfs_data_free(data);
Michael Holzheu2fcb3682011-01-05 12:47:43 +010057 return rc;
58}
59
Martin Schwidefsky07be0382014-01-24 09:18:52 +010060static long dbfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
61{
Al Viroa4555892014-10-21 20:11:25 -040062 struct hypfs_dbfs_file *df = file_inode(file)->i_private;
Martin Schwidefsky07be0382014-01-24 09:18:52 +010063 long rc;
64
Martin Schwidefsky07be0382014-01-24 09:18:52 +010065 mutex_lock(&df->lock);
66 if (df->unlocked_ioctl)
67 rc = df->unlocked_ioctl(file, cmd, arg);
68 else
69 rc = -ENOTTY;
70 mutex_unlock(&df->lock);
71 return rc;
72}
73
Michael Holzheu2fcb3682011-01-05 12:47:43 +010074static const struct file_operations dbfs_ops = {
75 .read = dbfs_read,
76 .llseek = no_llseek,
Martin Schwidefsky07be0382014-01-24 09:18:52 +010077 .unlocked_ioctl = dbfs_ioctl,
Michael Holzheu2fcb3682011-01-05 12:47:43 +010078};
79
80int hypfs_dbfs_create_file(struct hypfs_dbfs_file *df)
81{
82 df->dentry = debugfs_create_file(df->name, 0400, dbfs_dir, df,
83 &dbfs_ops);
84 if (IS_ERR(df->dentry))
85 return PTR_ERR(df->dentry);
86 mutex_init(&df->lock);
Michael Holzheu2fcb3682011-01-05 12:47:43 +010087 return 0;
88}
89
90void hypfs_dbfs_remove_file(struct hypfs_dbfs_file *df)
91{
92 debugfs_remove(df->dentry);
93}
94
95int hypfs_dbfs_init(void)
96{
97 dbfs_dir = debugfs_create_dir("s390_hypfs", NULL);
Rusty Russell8c6ffba2013-07-15 11:20:32 +093098 return PTR_ERR_OR_ZERO(dbfs_dir);
Michael Holzheu2fcb3682011-01-05 12:47:43 +010099}
100
101void hypfs_dbfs_exit(void)
102{
103 debugfs_remove(dbfs_dir);
104}