aboutsummaryrefslogtreecommitdiffstats
path: root/fs/debugfs
diff options
context:
space:
mode:
authorNicolai Stange <nicstange@gmail.com>2016-03-22 09:11:15 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-04-12 17:14:21 -0400
commitc64688081490321f2d23a292ef24e60bb321f3f1 (patch)
treea2fb5072922a286d0161b9125ca7c04ecf79fa0b /fs/debugfs
parent49d200deaa680501f19a247b1fffb29301e51d2b (diff)
debugfs: add support for self-protecting attribute file fops
In order to protect them against file removal issues, debugfs_create_file() creates a lifetime managing proxy around each struct file_operations handed in. In cases where this struct file_operations is able to manage file lifetime by itself already, the proxy created by debugfs is a waste of resources. The most common class of struct file_operations given to debugfs are those defined by means of the DEFINE_SIMPLE_ATTRIBUTE() macro. Introduce a DEFINE_DEBUGFS_ATTRIBUTE() macro to allow any struct file_operations of this class to be easily made file lifetime aware and thus, to be operated unproxied. Specifically, introduce debugfs_attr_read() and debugfs_attr_write() which wrap simple_attr_read() and simple_attr_write() under the protection of a debugfs_use_file_start()/debugfs_use_file_finish() pair. Make DEFINE_DEBUGFS_ATTRIBUTE() set the defined struct file_operations' ->read() and ->write() members to these wrappers. Export debugfs_create_file_unsafe() in order to allow debugfs users to create their files in non-proxying operation mode. Signed-off-by: Nicolai Stange <nicstange@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/debugfs')
-rw-r--r--fs/debugfs/file.c28
-rw-r--r--fs/debugfs/inode.c28
2 files changed, 56 insertions, 0 deletions
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index 6eb58a8ed03c..8ef56d9499a4 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -284,6 +284,34 @@ const struct file_operations debugfs_full_proxy_file_operations = {
284 .open = full_proxy_open, 284 .open = full_proxy_open,
285}; 285};
286 286
287ssize_t debugfs_attr_read(struct file *file, char __user *buf,
288 size_t len, loff_t *ppos)
289{
290 ssize_t ret;
291 int srcu_idx;
292
293 ret = debugfs_use_file_start(F_DENTRY(file), &srcu_idx);
294 if (likely(!ret))
295 ret = simple_attr_read(file, buf, len, ppos);
296 debugfs_use_file_finish(srcu_idx);
297 return ret;
298}
299EXPORT_SYMBOL_GPL(debugfs_attr_read);
300
301ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
302 size_t len, loff_t *ppos)
303{
304 ssize_t ret;
305 int srcu_idx;
306
307 ret = debugfs_use_file_start(F_DENTRY(file), &srcu_idx);
308 if (likely(!ret))
309 ret = simple_attr_write(file, buf, len, ppos);
310 debugfs_use_file_finish(srcu_idx);
311 return ret;
312}
313EXPORT_SYMBOL_GPL(debugfs_attr_write);
314
287static struct dentry *debugfs_create_mode(const char *name, umode_t mode, 315static struct dentry *debugfs_create_mode(const char *name, umode_t mode,
288 struct dentry *parent, void *value, 316 struct dentry *parent, void *value,
289 const struct file_operations *fops, 317 const struct file_operations *fops,
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 136f269f01de..41e079a8da26 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -369,6 +369,33 @@ struct dentry *debugfs_create_file(const char *name, umode_t mode,
369} 369}
370EXPORT_SYMBOL_GPL(debugfs_create_file); 370EXPORT_SYMBOL_GPL(debugfs_create_file);
371 371
372/**
373 * debugfs_create_file_unsafe - create a file in the debugfs filesystem
374 * @name: a pointer to a string containing the name of the file to create.
375 * @mode: the permission that the file should have.
376 * @parent: a pointer to the parent dentry for this file. This should be a
377 * directory dentry if set. If this parameter is NULL, then the
378 * file will be created in the root of the debugfs filesystem.
379 * @data: a pointer to something that the caller will want to get to later
380 * on. The inode.i_private pointer will point to this value on
381 * the open() call.
382 * @fops: a pointer to a struct file_operations that should be used for
383 * this file.
384 *
385 * debugfs_create_file_unsafe() is completely analogous to
386 * debugfs_create_file(), the only difference being that the fops
387 * handed it will not get protected against file removals by the
388 * debugfs core.
389 *
390 * It is your responsibility to protect your struct file_operation
391 * methods against file removals by means of debugfs_use_file_start()
392 * and debugfs_use_file_finish(). ->open() is still protected by
393 * debugfs though.
394 *
395 * Any struct file_operations defined by means of
396 * DEFINE_DEBUGFS_ATTRIBUTE() is protected against file removals and
397 * thus, may be used here.
398 */
372struct dentry *debugfs_create_file_unsafe(const char *name, umode_t mode, 399struct dentry *debugfs_create_file_unsafe(const char *name, umode_t mode,
373 struct dentry *parent, void *data, 400 struct dentry *parent, void *data,
374 const struct file_operations *fops) 401 const struct file_operations *fops)
@@ -379,6 +406,7 @@ struct dentry *debugfs_create_file_unsafe(const char *name, umode_t mode,
379 &debugfs_noop_file_operations, 406 &debugfs_noop_file_operations,
380 fops); 407 fops);
381} 408}
409EXPORT_SYMBOL_GPL(debugfs_create_file_unsafe);
382 410
383/** 411/**
384 * debugfs_create_file_size - create a file in the debugfs filesystem 412 * debugfs_create_file_size - create a file in the debugfs filesystem