mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-20 05:31:15 +00:00
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>
This commit is contained in:
parent
49d200deaa
commit
c646880814
3 changed files with 82 additions and 0 deletions
|
@ -50,6 +50,9 @@ extern struct srcu_struct debugfs_srcu;
|
|||
struct dentry *debugfs_create_file(const char *name, umode_t mode,
|
||||
struct dentry *parent, void *data,
|
||||
const struct file_operations *fops);
|
||||
struct dentry *debugfs_create_file_unsafe(const char *name, umode_t mode,
|
||||
struct dentry *parent, void *data,
|
||||
const struct file_operations *fops);
|
||||
|
||||
struct dentry *debugfs_create_file_size(const char *name, umode_t mode,
|
||||
struct dentry *parent, void *data,
|
||||
|
@ -74,6 +77,26 @@ int debugfs_use_file_start(const struct dentry *dentry, int *srcu_idx)
|
|||
|
||||
void debugfs_use_file_finish(int srcu_idx) __releases(&debugfs_srcu);
|
||||
|
||||
ssize_t debugfs_attr_read(struct file *file, char __user *buf,
|
||||
size_t len, loff_t *ppos);
|
||||
ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
|
||||
size_t len, loff_t *ppos);
|
||||
|
||||
#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt) \
|
||||
static int __fops ## _open(struct inode *inode, struct file *file) \
|
||||
{ \
|
||||
__simple_attr_check_format(__fmt, 0ull); \
|
||||
return simple_attr_open(inode, file, __get, __set, __fmt); \
|
||||
} \
|
||||
static const struct file_operations __fops = { \
|
||||
.owner = THIS_MODULE, \
|
||||
.open = __fops ## _open, \
|
||||
.release = simple_attr_release, \
|
||||
.read = debugfs_attr_read, \
|
||||
.write = debugfs_attr_write, \
|
||||
.llseek = generic_file_llseek, \
|
||||
}
|
||||
|
||||
struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
|
||||
struct dentry *new_dir, const char *new_name);
|
||||
|
||||
|
@ -193,6 +216,9 @@ static inline void debugfs_use_file_finish(int srcu_idx)
|
|||
__releases(&debugfs_srcu)
|
||||
{ }
|
||||
|
||||
#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt) \
|
||||
static const struct file_operations __fops = { 0 }
|
||||
|
||||
static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
|
||||
struct dentry *new_dir, char *new_name)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue