Blame view

fs/debugfs/file.c 12.3 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  /*
   *  file.c - part of debugfs, a tiny little debug file system
   *
   *  Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
   *  Copyright (C) 2004 IBM Inc.
   *
   *	This program is free software; you can redistribute it and/or
   *	modify it under the terms of the GNU General Public License version
   *	2 as published by the Free Software Foundation.
   *
   *  debugfs is for people to use instead of /proc or /sys.
   *  See Documentation/DocBook/kernel-api for more details.
   *
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
16
17
  #include <linux/module.h>
  #include <linux/fs.h>
  #include <linux/pagemap.h>
66f549639   Peter Oberparleiter   debugfs: implemen...
18
  #include <linux/namei.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  #include <linux/debugfs.h>
  
  static ssize_t default_read_file(struct file *file, char __user *buf,
  				 size_t count, loff_t *ppos)
  {
  	return 0;
  }
  
  static ssize_t default_write_file(struct file *file, const char __user *buf,
  				   size_t count, loff_t *ppos)
  {
  	return count;
  }
  
  static int default_open(struct inode *inode, struct file *file)
  {
8e18e2941   Theodore Ts'o   [PATCH] inode_die...
35
36
  	if (inode->i_private)
  		file->private_data = inode->i_private;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
38
39
  
  	return 0;
  }
4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
40
  const struct file_operations debugfs_file_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
42
43
44
  	.read =		default_read_file,
  	.write =	default_write_file,
  	.open =		default_open,
  };
66f549639   Peter Oberparleiter   debugfs: implemen...
45
46
47
48
49
50
51
52
53
54
  static void *debugfs_follow_link(struct dentry *dentry, struct nameidata *nd)
  {
  	nd_set_link(nd, dentry->d_inode->i_private);
  	return NULL;
  }
  
  const struct inode_operations debugfs_link_operations = {
  	.readlink       = generic_readlink,
  	.follow_link    = debugfs_follow_link,
  };
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
55
56
57
58
59
60
61
62
63
64
  static void debugfs_u8_set(void *data, u64 val)
  {
  	*(u8 *)data = val;
  }
  static u64 debugfs_u8_get(void *data)
  {
  	return *(u8 *)data;
  }
  DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
66
  
  /**
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
67
   * debugfs_create_u8 - create a debugfs file that is used to read and write an unsigned 8-bit value
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
69
70
   * @name: a pointer to a string containing the name of the file to create.
   * @mode: the permission that the file should have
   * @parent: a pointer to the parent dentry for this file.  This should be a
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
71
   *          directory dentry if set.  If this parameter is %NULL, then the
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72
73
74
75
76
77
78
79
80
81
82
   *          file will be created in the root of the debugfs filesystem.
   * @value: a pointer to the variable that the file should read to and write
   *         from.
   *
   * This function creates a file in debugfs with the given name that
   * contains the value of the variable @value.  If the @mode variable is so
   * set, it can be read from, and written to.
   *
   * This function will return a pointer to a dentry if it succeeds.  This
   * pointer must be passed to the debugfs_remove() function when the file is
   * to be removed (no automatic cleanup happens if your module is unloaded,
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
83
   * you are responsible here.)  If an error occurs, %NULL will be returned.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
   *
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
85
   * If debugfs is not enabled in the kernel, the value -%ENODEV will be
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
   * returned.  It is not wise to check for this value, but rather, check for
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
87
   * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
89
90
91
92
93
94
95
   * code.
   */
  struct dentry *debugfs_create_u8(const char *name, mode_t mode,
  				 struct dentry *parent, u8 *value)
  {
  	return debugfs_create_file(name, mode, parent, value, &fops_u8);
  }
  EXPORT_SYMBOL_GPL(debugfs_create_u8);
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
96
97
98
99
100
101
102
103
104
105
  static void debugfs_u16_set(void *data, u64 val)
  {
  	*(u16 *)data = val;
  }
  static u64 debugfs_u16_get(void *data)
  {
  	return *(u16 *)data;
  }
  DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
106
  /**
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
107
   * debugfs_create_u16 - create a debugfs file that is used to read and write an unsigned 16-bit value
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108
109
110
   * @name: a pointer to a string containing the name of the file to create.
   * @mode: the permission that the file should have
   * @parent: a pointer to the parent dentry for this file.  This should be a
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
111
   *          directory dentry if set.  If this parameter is %NULL, then the
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112
113
114
115
116
117
118
119
120
121
122
   *          file will be created in the root of the debugfs filesystem.
   * @value: a pointer to the variable that the file should read to and write
   *         from.
   *
   * This function creates a file in debugfs with the given name that
   * contains the value of the variable @value.  If the @mode variable is so
   * set, it can be read from, and written to.
   *
   * This function will return a pointer to a dentry if it succeeds.  This
   * pointer must be passed to the debugfs_remove() function when the file is
   * to be removed (no automatic cleanup happens if your module is unloaded,
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
123
   * you are responsible here.)  If an error occurs, %NULL will be returned.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
   *
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
125
   * If debugfs is not enabled in the kernel, the value -%ENODEV will be
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
126
   * returned.  It is not wise to check for this value, but rather, check for
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
127
   * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
130
131
132
133
134
135
   * code.
   */
  struct dentry *debugfs_create_u16(const char *name, mode_t mode,
  				  struct dentry *parent, u16 *value)
  {
  	return debugfs_create_file(name, mode, parent, value, &fops_u16);
  }
  EXPORT_SYMBOL_GPL(debugfs_create_u16);
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
136
137
138
139
140
141
142
143
144
145
  static void debugfs_u32_set(void *data, u64 val)
  {
  	*(u32 *)data = val;
  }
  static u64 debugfs_u32_get(void *data)
  {
  	return *(u32 *)data;
  }
  DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
146
  /**
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
147
   * debugfs_create_u32 - create a debugfs file that is used to read and write an unsigned 32-bit value
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148
149
150
   * @name: a pointer to a string containing the name of the file to create.
   * @mode: the permission that the file should have
   * @parent: a pointer to the parent dentry for this file.  This should be a
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
151
   *          directory dentry if set.  If this parameter is %NULL, then the
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
153
154
155
156
157
158
159
160
161
162
   *          file will be created in the root of the debugfs filesystem.
   * @value: a pointer to the variable that the file should read to and write
   *         from.
   *
   * This function creates a file in debugfs with the given name that
   * contains the value of the variable @value.  If the @mode variable is so
   * set, it can be read from, and written to.
   *
   * This function will return a pointer to a dentry if it succeeds.  This
   * pointer must be passed to the debugfs_remove() function when the file is
   * to be removed (no automatic cleanup happens if your module is unloaded,
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
163
   * you are responsible here.)  If an error occurs, %NULL will be returned.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164
   *
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
165
   * If debugfs is not enabled in the kernel, the value -%ENODEV will be
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166
   * returned.  It is not wise to check for this value, but rather, check for
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
167
   * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
169
170
171
172
173
174
175
   * code.
   */
  struct dentry *debugfs_create_u32(const char *name, mode_t mode,
  				 struct dentry *parent, u32 *value)
  {
  	return debugfs_create_file(name, mode, parent, value, &fops_u32);
  }
  EXPORT_SYMBOL_GPL(debugfs_create_u32);
8447891fe   Michael Ellerman   debugfs: Add debu...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
  static void debugfs_u64_set(void *data, u64 val)
  {
  	*(u64 *)data = val;
  }
  
  static u64 debugfs_u64_get(void *data)
  {
  	return *(u64 *)data;
  }
  DEFINE_SIMPLE_ATTRIBUTE(fops_u64, debugfs_u64_get, debugfs_u64_set, "%llu
  ");
  
  /**
   * debugfs_create_u64 - create a debugfs file that is used to read and write an unsigned 64-bit value
   * @name: a pointer to a string containing the name of the file to create.
   * @mode: the permission that the file should have
   * @parent: a pointer to the parent dentry for this file.  This should be a
   *          directory dentry if set.  If this parameter is %NULL, then the
   *          file will be created in the root of the debugfs filesystem.
   * @value: a pointer to the variable that the file should read to and write
   *         from.
   *
   * This function creates a file in debugfs with the given name that
   * contains the value of the variable @value.  If the @mode variable is so
   * set, it can be read from, and written to.
   *
   * This function will return a pointer to a dentry if it succeeds.  This
   * pointer must be passed to the debugfs_remove() function when the file is
   * to be removed (no automatic cleanup happens if your module is unloaded,
   * you are responsible here.)  If an error occurs, %NULL will be returned.
   *
   * If debugfs is not enabled in the kernel, the value -%ENODEV will be
   * returned.  It is not wise to check for this value, but rather, check for
   * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
   * code.
   */
  struct dentry *debugfs_create_u64(const char *name, mode_t mode,
  				 struct dentry *parent, u64 *value)
  {
  	return debugfs_create_file(name, mode, parent, value, &fops_u64);
  }
  EXPORT_SYMBOL_GPL(debugfs_create_u64);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
  static ssize_t read_file_bool(struct file *file, char __user *user_buf,
  			      size_t count, loff_t *ppos)
  {
  	char buf[3];
  	u32 *val = file->private_data;
  	
  	if (*val)
  		buf[0] = 'Y';
  	else
  		buf[0] = 'N';
  	buf[1] = '
  ';
  	buf[2] = 0x00;
  	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
  }
  
  static ssize_t write_file_bool(struct file *file, const char __user *user_buf,
  			       size_t count, loff_t *ppos)
  {
  	char buf[32];
  	int buf_size;
  	u32 *val = file->private_data;
  
  	buf_size = min(count, (sizeof(buf)-1));
  	if (copy_from_user(buf, user_buf, buf_size))
  		return -EFAULT;
  
  	switch (buf[0]) {
  	case 'y':
  	case 'Y':
  	case '1':
  		*val = 1;
  		break;
  	case 'n':
  	case 'N':
  	case '0':
  		*val = 0;
  		break;
  	}
  	
  	return count;
  }
4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
260
  static const struct file_operations fops_bool = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
261
262
263
264
265
266
  	.read =		read_file_bool,
  	.write =	write_file_bool,
  	.open =		default_open,
  };
  
  /**
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
267
   * debugfs_create_bool - create a debugfs file that is used to read and write a boolean value
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
268
269
270
   * @name: a pointer to a string containing the name of the file to create.
   * @mode: the permission that the file should have
   * @parent: a pointer to the parent dentry for this file.  This should be a
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
271
   *          directory dentry if set.  If this parameter is %NULL, then the
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272
273
274
275
276
277
278
279
280
281
282
   *          file will be created in the root of the debugfs filesystem.
   * @value: a pointer to the variable that the file should read to and write
   *         from.
   *
   * This function creates a file in debugfs with the given name that
   * contains the value of the variable @value.  If the @mode variable is so
   * set, it can be read from, and written to.
   *
   * This function will return a pointer to a dentry if it succeeds.  This
   * pointer must be passed to the debugfs_remove() function when the file is
   * to be removed (no automatic cleanup happens if your module is unloaded,
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
283
   * you are responsible here.)  If an error occurs, %NULL will be returned.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
   *
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
285
   * If debugfs is not enabled in the kernel, the value -%ENODEV will be
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
286
   * returned.  It is not wise to check for this value, but rather, check for
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
287
   * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
289
290
291
292
293
294
295
   * code.
   */
  struct dentry *debugfs_create_bool(const char *name, mode_t mode,
  				   struct dentry *parent, u32 *value)
  {
  	return debugfs_create_file(name, mode, parent, value, &fops_bool);
  }
  EXPORT_SYMBOL_GPL(debugfs_create_bool);
dd308bc35   Michael Ellerman   [PATCH] debugfs: ...
296
297
298
299
300
301
302
  static ssize_t read_file_blob(struct file *file, char __user *user_buf,
  			      size_t count, loff_t *ppos)
  {
  	struct debugfs_blob_wrapper *blob = file->private_data;
  	return simple_read_from_buffer(user_buf, count, ppos, blob->data,
  			blob->size);
  }
00977a59b   Arjan van de Ven   [PATCH] mark stru...
303
  static const struct file_operations fops_blob = {
dd308bc35   Michael Ellerman   [PATCH] debugfs: ...
304
305
306
307
308
  	.read =		read_file_blob,
  	.open =		default_open,
  };
  
  /**
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
309
   * debugfs_create_blob - create a debugfs file that is used to read and write a binary blob
dd308bc35   Michael Ellerman   [PATCH] debugfs: ...
310
311
312
   * @name: a pointer to a string containing the name of the file to create.
   * @mode: the permission that the file should have
   * @parent: a pointer to the parent dentry for this file.  This should be a
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
313
   *          directory dentry if set.  If this parameter is %NULL, then the
dd308bc35   Michael Ellerman   [PATCH] debugfs: ...
314
315
316
317
318
319
320
321
322
323
324
   *          file will be created in the root of the debugfs filesystem.
   * @blob: a pointer to a struct debugfs_blob_wrapper which contains a pointer
   *        to the blob data and the size of the data.
   *
   * This function creates a file in debugfs with the given name that exports
   * @blob->data as a binary blob. If the @mode variable is so set it can be
   * read from. Writing is not supported.
   *
   * This function will return a pointer to a dentry if it succeeds.  This
   * pointer must be passed to the debugfs_remove() function when the file is
   * to be removed (no automatic cleanup happens if your module is unloaded,
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
325
   * you are responsible here.)  If an error occurs, %NULL will be returned.
dd308bc35   Michael Ellerman   [PATCH] debugfs: ...
326
   *
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
327
   * If debugfs is not enabled in the kernel, the value -%ENODEV will be
dd308bc35   Michael Ellerman   [PATCH] debugfs: ...
328
   * returned.  It is not wise to check for this value, but rather, check for
6468b3afa   Randy Dunlap   Debugfs: kernel-d...
329
   * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
dd308bc35   Michael Ellerman   [PATCH] debugfs: ...
330
331
332
333
334
335
336
337
338
   * code.
   */
  struct dentry *debugfs_create_blob(const char *name, mode_t mode,
  				   struct dentry *parent,
  				   struct debugfs_blob_wrapper *blob)
  {
  	return debugfs_create_file(name, mode, parent, blob, &fops_blob);
  }
  EXPORT_SYMBOL_GPL(debugfs_create_blob);