2011-01-05 12:47:43 +01:00
/*
* Hypervisor filesystem for Linux on s390 - debugfs interface
*
2012-07-20 11:15:04 +02:00
* Copyright IBM Corp . 2010
2011-01-05 12:47:43 +01:00
* Author ( s ) : Michael Holzheu < holzheu @ linux . vnet . ibm . com >
*/
# include <linux/slab.h>
# include "hypfs.h"
static struct dentry * dbfs_dir ;
static struct hypfs_dbfs_data * hypfs_dbfs_data_alloc ( struct hypfs_dbfs_file * f )
{
struct hypfs_dbfs_data * data ;
data = kmalloc ( sizeof ( * data ) , GFP_KERNEL ) ;
if ( ! data )
return NULL ;
data - > dbfs_file = f ;
return data ;
}
2015-02-09 14:49:32 +01:00
static void hypfs_dbfs_data_free ( struct hypfs_dbfs_data * data )
2011-01-05 12:47:43 +01:00
{
data - > dbfs_file - > data_free ( data - > buf_free_ptr ) ;
kfree ( data ) ;
}
static ssize_t dbfs_read ( struct file * file , char __user * buf ,
size_t size , loff_t * ppos )
{
struct hypfs_dbfs_data * data ;
struct hypfs_dbfs_file * df ;
ssize_t rc ;
if ( * ppos ! = 0 )
return 0 ;
2013-01-23 17:07:38 -05:00
df = file_inode ( file ) - > i_private ;
2011-01-05 12:47:43 +01:00
mutex_lock ( & df - > lock ) ;
2015-02-09 14:49:32 +01:00
data = hypfs_dbfs_data_alloc ( df ) ;
if ( ! data ) {
mutex_unlock ( & df - > lock ) ;
return - ENOMEM ;
}
rc = df - > data_create ( & data - > buf , & data - > buf_free_ptr , & data - > size ) ;
if ( rc ) {
mutex_unlock ( & df - > lock ) ;
kfree ( data ) ;
return rc ;
2011-01-05 12:47:43 +01:00
}
mutex_unlock ( & df - > lock ) ;
rc = simple_read_from_buffer ( buf , size , ppos , data - > buf , data - > size ) ;
2015-02-09 14:49:32 +01:00
hypfs_dbfs_data_free ( data ) ;
2011-01-05 12:47:43 +01:00
return rc ;
}
2014-01-24 09:18:52 +01:00
static long dbfs_ioctl ( struct file * file , unsigned int cmd , unsigned long arg )
{
2014-10-21 20:11:25 -04:00
struct hypfs_dbfs_file * df = file_inode ( file ) - > i_private ;
2014-01-24 09:18:52 +01:00
long rc ;
mutex_lock ( & df - > lock ) ;
if ( df - > unlocked_ioctl )
rc = df - > unlocked_ioctl ( file , cmd , arg ) ;
else
rc = - ENOTTY ;
mutex_unlock ( & df - > lock ) ;
return rc ;
}
2011-01-05 12:47:43 +01:00
static const struct file_operations dbfs_ops = {
. read = dbfs_read ,
. llseek = no_llseek ,
2014-01-24 09:18:52 +01:00
. unlocked_ioctl = dbfs_ioctl ,
2011-01-05 12:47:43 +01:00
} ;
int hypfs_dbfs_create_file ( struct hypfs_dbfs_file * df )
{
df - > dentry = debugfs_create_file ( df - > name , 0400 , dbfs_dir , df ,
& dbfs_ops ) ;
if ( IS_ERR ( df - > dentry ) )
return PTR_ERR ( df - > dentry ) ;
mutex_init ( & df - > lock ) ;
return 0 ;
}
void hypfs_dbfs_remove_file ( struct hypfs_dbfs_file * df )
{
debugfs_remove ( df - > dentry ) ;
}
int hypfs_dbfs_init ( void )
{
dbfs_dir = debugfs_create_dir ( " s390_hypfs " , NULL ) ;
2013-07-15 11:20:32 +09:30
return PTR_ERR_OR_ZERO ( dbfs_dir ) ;
2011-01-05 12:47:43 +01:00
}
void hypfs_dbfs_exit ( void )
{
debugfs_remove ( dbfs_dir ) ;
}