2 * Hypervisor filesystem for Linux on s390 - debugfs interface
4 * Copyright IBM Corp. 2010
5 * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
8 #include <linux/slab.h>
11 static struct dentry
*dbfs_dir
;
13 static struct hypfs_dbfs_data
*hypfs_dbfs_data_alloc(struct hypfs_dbfs_file
*f
)
15 struct hypfs_dbfs_data
*data
;
17 data
= kmalloc(sizeof(*data
), GFP_KERNEL
);
20 kref_init(&data
->kref
);
25 static void hypfs_dbfs_data_free(struct kref
*kref
)
27 struct hypfs_dbfs_data
*data
;
29 data
= container_of(kref
, struct hypfs_dbfs_data
, kref
);
30 data
->dbfs_file
->data_free(data
->buf_free_ptr
);
34 static void data_free_delayed(struct work_struct
*work
)
36 struct hypfs_dbfs_data
*data
;
37 struct hypfs_dbfs_file
*df
;
39 df
= container_of(work
, struct hypfs_dbfs_file
, data_free_work
.work
);
40 mutex_lock(&df
->lock
);
43 mutex_unlock(&df
->lock
);
44 kref_put(&data
->kref
, hypfs_dbfs_data_free
);
47 static ssize_t
dbfs_read(struct file
*file
, char __user
*buf
,
48 size_t size
, loff_t
*ppos
)
50 struct hypfs_dbfs_data
*data
;
51 struct hypfs_dbfs_file
*df
;
57 df
= file_inode(file
)->i_private
;
58 mutex_lock(&df
->lock
);
60 data
= hypfs_dbfs_data_alloc(df
);
62 mutex_unlock(&df
->lock
);
65 rc
= df
->data_create(&data
->buf
, &data
->buf_free_ptr
,
68 mutex_unlock(&df
->lock
);
73 schedule_delayed_work(&df
->data_free_work
, HZ
);
76 kref_get(&data
->kref
);
77 mutex_unlock(&df
->lock
);
79 rc
= simple_read_from_buffer(buf
, size
, ppos
, data
->buf
, data
->size
);
80 kref_put(&data
->kref
, hypfs_dbfs_data_free
);
84 static long dbfs_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
86 struct hypfs_dbfs_file
*df
;
89 df
= file
->f_path
.dentry
->d_inode
->i_private
;
90 mutex_lock(&df
->lock
);
91 if (df
->unlocked_ioctl
)
92 rc
= df
->unlocked_ioctl(file
, cmd
, arg
);
95 mutex_unlock(&df
->lock
);
99 static const struct file_operations dbfs_ops
= {
102 .unlocked_ioctl
= dbfs_ioctl
,
105 int hypfs_dbfs_create_file(struct hypfs_dbfs_file
*df
)
107 df
->dentry
= debugfs_create_file(df
->name
, 0400, dbfs_dir
, df
,
109 if (IS_ERR(df
->dentry
))
110 return PTR_ERR(df
->dentry
);
111 mutex_init(&df
->lock
);
112 INIT_DELAYED_WORK(&df
->data_free_work
, data_free_delayed
);
116 void hypfs_dbfs_remove_file(struct hypfs_dbfs_file
*df
)
118 debugfs_remove(df
->dentry
);
121 int hypfs_dbfs_init(void)
123 dbfs_dir
= debugfs_create_dir("s390_hypfs", NULL
);
124 return PTR_ERR_OR_ZERO(dbfs_dir
);
127 void hypfs_dbfs_exit(void)
129 debugfs_remove(dbfs_dir
);