Blame view

kernel/linux-rt-4.4.41/arch/s390/hypfs/hypfs_dbfs.c 2.11 KB
5113f6f70   김현기   kernel add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
  /*
   * Hypervisor filesystem for Linux on s390 - debugfs interface
   *
   * Copyright IBM Corp. 2010
   * 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;
  }
  
  static void hypfs_dbfs_data_free(struct hypfs_dbfs_data *data)
  {
  	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;
  
  	df = file_inode(file)->i_private;
  	mutex_lock(&df->lock);
  	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;
  	}
  	mutex_unlock(&df->lock);
  
  	rc = simple_read_from_buffer(buf, size, ppos, data->buf, data->size);
  	hypfs_dbfs_data_free(data);
  	return rc;
  }
  
  static long dbfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  {
  	struct hypfs_dbfs_file *df = file_inode(file)->i_private;
  	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;
  }
  
  static const struct file_operations dbfs_ops = {
  	.read		= dbfs_read,
  	.llseek		= no_llseek,
  	.unlocked_ioctl = dbfs_ioctl,
  };
  
  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);
  	return PTR_ERR_OR_ZERO(dbfs_dir);
  }
  
  void hypfs_dbfs_exit(void)
  {
  	debugfs_remove(dbfs_dir);
  }