aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/hypfs/hypfs_dbfs.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-07 17:50:50 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-07 17:50:50 -0500
commitfb5131e1880ea1ba3ba7197cd5cc66c9c288f715 (patch)
treef0d9f25f9079727b9ead5a2b4cc85a0fea9b4668 /arch/s390/hypfs/hypfs_dbfs.c
parentd074b104cefcb6e8ded55a53e62fed59a246f55d (diff)
parent8e1023016cf17152972b98bce6c144834a4916d5 (diff)
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: (65 commits) [S390] prevent unneccesary loops_per_jiffy recalculation [S390] cpuinfo: use get_online_cpus() instead of preempt_disable() [S390] smp: remove cpu hotplug messages [S390] mutex: enable spinning mutex on s390 [S390] mutex: Introduce arch_mutex_cpu_relax() [S390] cio: fix ccwgroup unregistration race condition [S390] perf: add DWARF register lookup for s390 [S390] cleanup ftrace backend functions [S390] ptrace cleanup [S390] smp/idle: call init_idle() before starting a new cpu [S390] smp: delay idle task creation [S390] dasd: Correct retry counter for terminated I/O. [S390] dasd: Add support for raw ECKD access. [S390] dasd: Prevent deadlock during suspend/resume. [S390] dasd: Improve handling of stolen DASD reservation [S390] dasd: do path verification for paths added at runtime [S390] dasd: add High Performance FICON multitrack support [S390] cio: reduce memory consumption of itcw structures [S390] nmi: enable machine checks early [S390] qeth: buffer count imbalance ...
Diffstat (limited to 'arch/s390/hypfs/hypfs_dbfs.c')
-rw-r--r--arch/s390/hypfs/hypfs_dbfs.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/arch/s390/hypfs/hypfs_dbfs.c b/arch/s390/hypfs/hypfs_dbfs.c
new file mode 100644
index 000000000000..b478013b7fec
--- /dev/null
+++ b/arch/s390/hypfs/hypfs_dbfs.c
@@ -0,0 +1,116 @@
1/*
2 * Hypervisor filesystem for Linux on s390 - debugfs interface
3 *
4 * Copyright (C) IBM Corp. 2010
5 * 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;
20 kref_init(&data->kref);
21 data->dbfs_file = f;
22 return data;
23}
24
25static void hypfs_dbfs_data_free(struct kref *kref)
26{
27 struct hypfs_dbfs_data *data;
28
29 data = container_of(kref, struct hypfs_dbfs_data, kref);
30 data->dbfs_file->data_free(data->buf_free_ptr);
31 kfree(data);
32}
33
34static void data_free_delayed(struct work_struct *work)
35{
36 struct hypfs_dbfs_data *data;
37 struct hypfs_dbfs_file *df;
38
39 df = container_of(work, struct hypfs_dbfs_file, data_free_work.work);
40 mutex_lock(&df->lock);
41 data = df->data;
42 df->data = NULL;
43 mutex_unlock(&df->lock);
44 kref_put(&data->kref, hypfs_dbfs_data_free);
45}
46
47static ssize_t dbfs_read(struct file *file, char __user *buf,
48 size_t size, loff_t *ppos)
49{
50 struct hypfs_dbfs_data *data;
51 struct hypfs_dbfs_file *df;
52 ssize_t rc;
53
54 if (*ppos != 0)
55 return 0;
56
57 df = file->f_path.dentry->d_inode->i_private;
58 mutex_lock(&df->lock);
59 if (!df->data) {
60 data = hypfs_dbfs_data_alloc(df);
61 if (!data) {
62 mutex_unlock(&df->lock);
63 return -ENOMEM;
64 }
65 rc = df->data_create(&data->buf, &data->buf_free_ptr,
66 &data->size);
67 if (rc) {
68 mutex_unlock(&df->lock);
69 kfree(data);
70 return rc;
71 }
72 df->data = data;
73 schedule_delayed_work(&df->data_free_work, HZ);
74 }
75 data = df->data;
76 kref_get(&data->kref);
77 mutex_unlock(&df->lock);
78
79 rc = simple_read_from_buffer(buf, size, ppos, data->buf, data->size);
80 kref_put(&data->kref, hypfs_dbfs_data_free);
81 return rc;
82}
83
84static const struct file_operations dbfs_ops = {
85 .read = dbfs_read,
86 .llseek = no_llseek,
87};
88
89int hypfs_dbfs_create_file(struct hypfs_dbfs_file *df)
90{
91 df->dentry = debugfs_create_file(df->name, 0400, dbfs_dir, df,
92 &dbfs_ops);
93 if (IS_ERR(df->dentry))
94 return PTR_ERR(df->dentry);
95 mutex_init(&df->lock);
96 INIT_DELAYED_WORK(&df->data_free_work, data_free_delayed);
97 return 0;
98}
99
100void hypfs_dbfs_remove_file(struct hypfs_dbfs_file *df)
101{
102 debugfs_remove(df->dentry);
103}
104
105int hypfs_dbfs_init(void)
106{
107 dbfs_dir = debugfs_create_dir("s390_hypfs", NULL);
108 if (IS_ERR(dbfs_dir))
109 return PTR_ERR(dbfs_dir);
110 return 0;
111}
112
113void hypfs_dbfs_exit(void)
114{
115 debugfs_remove(dbfs_dir);
116}