Loading drivers/infiniband/hw/hfi1/debugfs.c +10 −10 Original line number Diff line number Diff line Loading @@ -71,13 +71,13 @@ static ssize_t hfi1_seq_read( loff_t *ppos) { struct dentry *d = file->f_path.dentry; int srcu_idx; ssize_t r; r = debugfs_use_file_start(d, &srcu_idx); if (likely(!r)) r = debugfs_file_get(d); if (unlikely(r)) return r; r = seq_read(file, buf, size, ppos); debugfs_use_file_finish(srcu_idx); debugfs_file_put(d); return r; } Loading @@ -87,13 +87,13 @@ static loff_t hfi1_seq_lseek( int whence) { struct dentry *d = file->f_path.dentry; int srcu_idx; loff_t r; r = debugfs_use_file_start(d, &srcu_idx); if (likely(!r)) r = debugfs_file_get(d); if (unlikely(r)) return r; r = seq_lseek(file, offset, whence); debugfs_use_file_finish(srcu_idx); debugfs_file_put(d); return r; } Loading fs/debugfs/file.c +99 −61 Original line number Diff line number Diff line Loading @@ -98,28 +98,69 @@ EXPORT_SYMBOL_GPL(debugfs_use_file_finish); #define F_DENTRY(filp) ((filp)->f_path.dentry) const struct file_operations *debugfs_real_fops(const struct file *filp) __must_hold(&debugfs_srcu) { struct debugfs_fsdata *fsd = F_DENTRY(filp)->d_fsdata; /* * Neither the pointer to the struct file_operations, nor its * contents ever change -- srcu_dereference() is not needed here. */ return fsd->real_fops; } EXPORT_SYMBOL_GPL(debugfs_real_fops); /** * debugfs_file_get - mark the beginning of file data access * @dentry: the dentry object whose data is being accessed. * * Up to a matching call to debugfs_file_put(), any successive call * into the file removing functions debugfs_remove() and * debugfs_remove_recursive() will block. Since associated private * file data may only get freed after a successful return of any of * the removal functions, you may safely access it after a successful * call to debugfs_file_get() without worrying about lifetime issues. * * If -%EIO is returned, the file has already been removed and thus, * it is not safe to access any of its data. If, on the other hand, * it is allowed to access the file data, zero is returned. */ int debugfs_file_get(struct dentry *dentry) { struct debugfs_fsdata *fsd = dentry->d_fsdata; /* Avoid starvation of removers. */ if (d_unlinked(dentry)) return -EIO; if (!refcount_inc_not_zero(&fsd->active_users)) return -EIO; return 0; } EXPORT_SYMBOL_GPL(debugfs_file_get); /** * debugfs_file_put - mark the end of file data access * @dentry: the dentry object formerly passed to * debugfs_file_get(). * * Allow any ongoing concurrent call into debugfs_remove() or * debugfs_remove_recursive() blocked by a former call to * debugfs_file_get() to proceed and return to its caller. */ void debugfs_file_put(struct dentry *dentry) { struct debugfs_fsdata *fsd = dentry->d_fsdata; if (refcount_dec_and_test(&fsd->active_users)) complete(&fsd->active_users_drained); } EXPORT_SYMBOL_GPL(debugfs_file_put); static int open_proxy_open(struct inode *inode, struct file *filp) { const struct dentry *dentry = F_DENTRY(filp); struct dentry *dentry = F_DENTRY(filp); const struct file_operations *real_fops = NULL; int srcu_idx, r; int r = 0; r = debugfs_use_file_start(dentry, &srcu_idx); if (r) { r = -ENOENT; goto out; } if (debugfs_file_get(dentry)) return -ENOENT; real_fops = debugfs_real_fops(filp); real_fops = fops_get(real_fops); Loading @@ -136,7 +177,7 @@ static int open_proxy_open(struct inode *inode, struct file *filp) r = real_fops->open(inode, filp); out: debugfs_use_file_finish(srcu_idx); debugfs_file_put(dentry); return r; } Loading @@ -150,16 +191,16 @@ const struct file_operations debugfs_open_proxy_file_operations = { #define FULL_PROXY_FUNC(name, ret_type, filp, proto, args) \ static ret_type full_proxy_ ## name(proto) \ { \ const struct dentry *dentry = F_DENTRY(filp); \ struct dentry *dentry = F_DENTRY(filp); \ const struct file_operations *real_fops = \ debugfs_real_fops(filp); \ int srcu_idx; \ ret_type r; \ \ r = debugfs_use_file_start(dentry, &srcu_idx); \ if (likely(!r)) \ r = debugfs_file_get(dentry); \ if (unlikely(r)) \ return r; \ r = real_fops->name(args); \ debugfs_use_file_finish(srcu_idx); \ debugfs_file_put(dentry); \ return r; \ } Loading @@ -184,18 +225,15 @@ FULL_PROXY_FUNC(unlocked_ioctl, long, filp, static unsigned int full_proxy_poll(struct file *filp, struct poll_table_struct *wait) { const struct dentry *dentry = F_DENTRY(filp); const struct file_operations *real_fops = debugfs_real_fops(filp); int srcu_idx; struct dentry *dentry = F_DENTRY(filp); unsigned int r = 0; if (debugfs_use_file_start(dentry, &srcu_idx)) { debugfs_use_file_finish(srcu_idx); if (debugfs_file_get(dentry)) return POLLHUP; } r = real_fops->poll(filp, wait); debugfs_use_file_finish(srcu_idx); debugfs_file_put(dentry); return r; } Loading Loading @@ -239,16 +277,13 @@ static void __full_proxy_fops_init(struct file_operations *proxy_fops, static int full_proxy_open(struct inode *inode, struct file *filp) { const struct dentry *dentry = F_DENTRY(filp); struct dentry *dentry = F_DENTRY(filp); const struct file_operations *real_fops = NULL; struct file_operations *proxy_fops = NULL; int srcu_idx, r; int r = 0; r = debugfs_use_file_start(dentry, &srcu_idx); if (r) { r = -ENOENT; goto out; } if (debugfs_file_get(dentry)) return -ENOENT; real_fops = debugfs_real_fops(filp); real_fops = fops_get(real_fops); Loading Loading @@ -286,7 +321,7 @@ static int full_proxy_open(struct inode *inode, struct file *filp) kfree(proxy_fops); fops_put(real_fops); out: debugfs_use_file_finish(srcu_idx); debugfs_file_put(dentry); return r; } Loading @@ -297,13 +332,14 @@ const struct file_operations debugfs_full_proxy_file_operations = { ssize_t debugfs_attr_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) { struct dentry *dentry = F_DENTRY(file); ssize_t ret; int srcu_idx; ret = debugfs_use_file_start(F_DENTRY(file), &srcu_idx); if (likely(!ret)) ret = debugfs_file_get(dentry); if (unlikely(ret)) return ret; ret = simple_attr_read(file, buf, len, ppos); debugfs_use_file_finish(srcu_idx); debugfs_file_put(dentry); return ret; } EXPORT_SYMBOL_GPL(debugfs_attr_read); Loading @@ -311,13 +347,14 @@ EXPORT_SYMBOL_GPL(debugfs_attr_read); ssize_t debugfs_attr_write(struct file *file, const char __user *buf, size_t len, loff_t *ppos) { struct dentry *dentry = F_DENTRY(file); ssize_t ret; int srcu_idx; ret = debugfs_use_file_start(F_DENTRY(file), &srcu_idx); if (likely(!ret)) ret = debugfs_file_get(dentry); if (unlikely(ret)) return ret; ret = simple_attr_write(file, buf, len, ppos); debugfs_use_file_finish(srcu_idx); debugfs_file_put(dentry); return ret; } EXPORT_SYMBOL_GPL(debugfs_attr_write); Loading Loading @@ -751,14 +788,14 @@ ssize_t debugfs_read_file_bool(struct file *file, char __user *user_buf, { char buf[3]; bool val; int r, srcu_idx; int r; struct dentry *dentry = F_DENTRY(file); r = debugfs_use_file_start(F_DENTRY(file), &srcu_idx); if (likely(!r)) val = *(bool *)file->private_data; debugfs_use_file_finish(srcu_idx); if (r) r = debugfs_file_get(dentry); if (unlikely(r)) return r; val = *(bool *)file->private_data; debugfs_file_put(dentry); if (val) buf[0] = 'Y'; Loading @@ -776,8 +813,9 @@ ssize_t debugfs_write_file_bool(struct file *file, const char __user *user_buf, char buf[32]; size_t buf_size; bool bv; int r, srcu_idx; int r; bool *val = file->private_data; struct dentry *dentry = F_DENTRY(file); buf_size = min(count, (sizeof(buf)-1)); if (copy_from_user(buf, user_buf, buf_size)) Loading @@ -785,12 +823,11 @@ ssize_t debugfs_write_file_bool(struct file *file, const char __user *user_buf, buf[buf_size] = '\0'; if (strtobool(buf, &bv) == 0) { r = debugfs_use_file_start(F_DENTRY(file), &srcu_idx); if (likely(!r)) *val = bv; debugfs_use_file_finish(srcu_idx); if (r) r = debugfs_file_get(dentry); if (unlikely(r)) return r; *val = bv; debugfs_file_put(dentry); } return count; Loading Loading @@ -852,14 +889,15 @@ 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; struct dentry *dentry = F_DENTRY(file); ssize_t r; int srcu_idx; r = debugfs_use_file_start(F_DENTRY(file), &srcu_idx); if (likely(!r)) r = debugfs_file_get(dentry); if (unlikely(r)) return r; r = simple_read_from_buffer(user_buf, count, ppos, blob->data, blob->size); debugfs_use_file_finish(srcu_idx); debugfs_file_put(dentry); return r; } Loading fs/debugfs/inode.c +23 −6 Original line number Diff line number Diff line Loading @@ -374,6 +374,7 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode, inode->i_fop = proxy_fops; fsd->real_fops = real_fops; refcount_set(&fsd->active_users, 1); dentry->d_fsdata = fsd; d_instantiate(dentry, inode); Loading Loading @@ -631,18 +632,34 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, } EXPORT_SYMBOL_GPL(debugfs_create_symlink); static void __debugfs_remove_file(struct dentry *dentry, struct dentry *parent) { struct debugfs_fsdata *fsd; simple_unlink(d_inode(parent), dentry); d_delete(dentry); fsd = dentry->d_fsdata; init_completion(&fsd->active_users_drained); if (!refcount_dec_and_test(&fsd->active_users)) wait_for_completion(&fsd->active_users_drained); } static int __debugfs_remove(struct dentry *dentry, struct dentry *parent) { int ret = 0; if (simple_positive(dentry)) { dget(dentry); if (!d_is_reg(dentry)) { if (d_is_dir(dentry)) ret = simple_rmdir(d_inode(parent), dentry); else simple_unlink(d_inode(parent), dentry); if (!ret) d_delete(dentry); } else { __debugfs_remove_file(dentry, parent); } dput(dentry); } return ret; Loading fs/debugfs/internal.h +2 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ extern const struct file_operations debugfs_full_proxy_file_operations; struct debugfs_fsdata { const struct file_operations *real_fops; refcount_t active_users; struct completion active_users_drained; }; #endif /* _DEBUGFS_INTERNAL_H_ */ include/linux/debugfs.h +12 −2 Original line number Diff line number Diff line Loading @@ -95,8 +95,10 @@ int debugfs_use_file_start(const struct dentry *dentry, int *srcu_idx) void debugfs_use_file_finish(int srcu_idx) __releases(&debugfs_srcu); const struct file_operations *debugfs_real_fops(const struct file *filp) __must_hold(&debugfs_srcu); const struct file_operations *debugfs_real_fops(const struct file *filp); int debugfs_file_get(struct dentry *dentry); void debugfs_file_put(struct dentry *dentry); ssize_t debugfs_attr_read(struct file *file, char __user *buf, size_t len, loff_t *ppos); Loading Loading @@ -236,6 +238,14 @@ static inline void debugfs_use_file_finish(int srcu_idx) __releases(&debugfs_srcu) { } static inline int debugfs_file_get(struct dentry *dentry) { return 0; } static inline void debugfs_file_put(struct dentry *dentry) { } static inline ssize_t debugfs_attr_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) { Loading Loading
drivers/infiniband/hw/hfi1/debugfs.c +10 −10 Original line number Diff line number Diff line Loading @@ -71,13 +71,13 @@ static ssize_t hfi1_seq_read( loff_t *ppos) { struct dentry *d = file->f_path.dentry; int srcu_idx; ssize_t r; r = debugfs_use_file_start(d, &srcu_idx); if (likely(!r)) r = debugfs_file_get(d); if (unlikely(r)) return r; r = seq_read(file, buf, size, ppos); debugfs_use_file_finish(srcu_idx); debugfs_file_put(d); return r; } Loading @@ -87,13 +87,13 @@ static loff_t hfi1_seq_lseek( int whence) { struct dentry *d = file->f_path.dentry; int srcu_idx; loff_t r; r = debugfs_use_file_start(d, &srcu_idx); if (likely(!r)) r = debugfs_file_get(d); if (unlikely(r)) return r; r = seq_lseek(file, offset, whence); debugfs_use_file_finish(srcu_idx); debugfs_file_put(d); return r; } Loading
fs/debugfs/file.c +99 −61 Original line number Diff line number Diff line Loading @@ -98,28 +98,69 @@ EXPORT_SYMBOL_GPL(debugfs_use_file_finish); #define F_DENTRY(filp) ((filp)->f_path.dentry) const struct file_operations *debugfs_real_fops(const struct file *filp) __must_hold(&debugfs_srcu) { struct debugfs_fsdata *fsd = F_DENTRY(filp)->d_fsdata; /* * Neither the pointer to the struct file_operations, nor its * contents ever change -- srcu_dereference() is not needed here. */ return fsd->real_fops; } EXPORT_SYMBOL_GPL(debugfs_real_fops); /** * debugfs_file_get - mark the beginning of file data access * @dentry: the dentry object whose data is being accessed. * * Up to a matching call to debugfs_file_put(), any successive call * into the file removing functions debugfs_remove() and * debugfs_remove_recursive() will block. Since associated private * file data may only get freed after a successful return of any of * the removal functions, you may safely access it after a successful * call to debugfs_file_get() without worrying about lifetime issues. * * If -%EIO is returned, the file has already been removed and thus, * it is not safe to access any of its data. If, on the other hand, * it is allowed to access the file data, zero is returned. */ int debugfs_file_get(struct dentry *dentry) { struct debugfs_fsdata *fsd = dentry->d_fsdata; /* Avoid starvation of removers. */ if (d_unlinked(dentry)) return -EIO; if (!refcount_inc_not_zero(&fsd->active_users)) return -EIO; return 0; } EXPORT_SYMBOL_GPL(debugfs_file_get); /** * debugfs_file_put - mark the end of file data access * @dentry: the dentry object formerly passed to * debugfs_file_get(). * * Allow any ongoing concurrent call into debugfs_remove() or * debugfs_remove_recursive() blocked by a former call to * debugfs_file_get() to proceed and return to its caller. */ void debugfs_file_put(struct dentry *dentry) { struct debugfs_fsdata *fsd = dentry->d_fsdata; if (refcount_dec_and_test(&fsd->active_users)) complete(&fsd->active_users_drained); } EXPORT_SYMBOL_GPL(debugfs_file_put); static int open_proxy_open(struct inode *inode, struct file *filp) { const struct dentry *dentry = F_DENTRY(filp); struct dentry *dentry = F_DENTRY(filp); const struct file_operations *real_fops = NULL; int srcu_idx, r; int r = 0; r = debugfs_use_file_start(dentry, &srcu_idx); if (r) { r = -ENOENT; goto out; } if (debugfs_file_get(dentry)) return -ENOENT; real_fops = debugfs_real_fops(filp); real_fops = fops_get(real_fops); Loading @@ -136,7 +177,7 @@ static int open_proxy_open(struct inode *inode, struct file *filp) r = real_fops->open(inode, filp); out: debugfs_use_file_finish(srcu_idx); debugfs_file_put(dentry); return r; } Loading @@ -150,16 +191,16 @@ const struct file_operations debugfs_open_proxy_file_operations = { #define FULL_PROXY_FUNC(name, ret_type, filp, proto, args) \ static ret_type full_proxy_ ## name(proto) \ { \ const struct dentry *dentry = F_DENTRY(filp); \ struct dentry *dentry = F_DENTRY(filp); \ const struct file_operations *real_fops = \ debugfs_real_fops(filp); \ int srcu_idx; \ ret_type r; \ \ r = debugfs_use_file_start(dentry, &srcu_idx); \ if (likely(!r)) \ r = debugfs_file_get(dentry); \ if (unlikely(r)) \ return r; \ r = real_fops->name(args); \ debugfs_use_file_finish(srcu_idx); \ debugfs_file_put(dentry); \ return r; \ } Loading @@ -184,18 +225,15 @@ FULL_PROXY_FUNC(unlocked_ioctl, long, filp, static unsigned int full_proxy_poll(struct file *filp, struct poll_table_struct *wait) { const struct dentry *dentry = F_DENTRY(filp); const struct file_operations *real_fops = debugfs_real_fops(filp); int srcu_idx; struct dentry *dentry = F_DENTRY(filp); unsigned int r = 0; if (debugfs_use_file_start(dentry, &srcu_idx)) { debugfs_use_file_finish(srcu_idx); if (debugfs_file_get(dentry)) return POLLHUP; } r = real_fops->poll(filp, wait); debugfs_use_file_finish(srcu_idx); debugfs_file_put(dentry); return r; } Loading Loading @@ -239,16 +277,13 @@ static void __full_proxy_fops_init(struct file_operations *proxy_fops, static int full_proxy_open(struct inode *inode, struct file *filp) { const struct dentry *dentry = F_DENTRY(filp); struct dentry *dentry = F_DENTRY(filp); const struct file_operations *real_fops = NULL; struct file_operations *proxy_fops = NULL; int srcu_idx, r; int r = 0; r = debugfs_use_file_start(dentry, &srcu_idx); if (r) { r = -ENOENT; goto out; } if (debugfs_file_get(dentry)) return -ENOENT; real_fops = debugfs_real_fops(filp); real_fops = fops_get(real_fops); Loading Loading @@ -286,7 +321,7 @@ static int full_proxy_open(struct inode *inode, struct file *filp) kfree(proxy_fops); fops_put(real_fops); out: debugfs_use_file_finish(srcu_idx); debugfs_file_put(dentry); return r; } Loading @@ -297,13 +332,14 @@ const struct file_operations debugfs_full_proxy_file_operations = { ssize_t debugfs_attr_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) { struct dentry *dentry = F_DENTRY(file); ssize_t ret; int srcu_idx; ret = debugfs_use_file_start(F_DENTRY(file), &srcu_idx); if (likely(!ret)) ret = debugfs_file_get(dentry); if (unlikely(ret)) return ret; ret = simple_attr_read(file, buf, len, ppos); debugfs_use_file_finish(srcu_idx); debugfs_file_put(dentry); return ret; } EXPORT_SYMBOL_GPL(debugfs_attr_read); Loading @@ -311,13 +347,14 @@ EXPORT_SYMBOL_GPL(debugfs_attr_read); ssize_t debugfs_attr_write(struct file *file, const char __user *buf, size_t len, loff_t *ppos) { struct dentry *dentry = F_DENTRY(file); ssize_t ret; int srcu_idx; ret = debugfs_use_file_start(F_DENTRY(file), &srcu_idx); if (likely(!ret)) ret = debugfs_file_get(dentry); if (unlikely(ret)) return ret; ret = simple_attr_write(file, buf, len, ppos); debugfs_use_file_finish(srcu_idx); debugfs_file_put(dentry); return ret; } EXPORT_SYMBOL_GPL(debugfs_attr_write); Loading Loading @@ -751,14 +788,14 @@ ssize_t debugfs_read_file_bool(struct file *file, char __user *user_buf, { char buf[3]; bool val; int r, srcu_idx; int r; struct dentry *dentry = F_DENTRY(file); r = debugfs_use_file_start(F_DENTRY(file), &srcu_idx); if (likely(!r)) val = *(bool *)file->private_data; debugfs_use_file_finish(srcu_idx); if (r) r = debugfs_file_get(dentry); if (unlikely(r)) return r; val = *(bool *)file->private_data; debugfs_file_put(dentry); if (val) buf[0] = 'Y'; Loading @@ -776,8 +813,9 @@ ssize_t debugfs_write_file_bool(struct file *file, const char __user *user_buf, char buf[32]; size_t buf_size; bool bv; int r, srcu_idx; int r; bool *val = file->private_data; struct dentry *dentry = F_DENTRY(file); buf_size = min(count, (sizeof(buf)-1)); if (copy_from_user(buf, user_buf, buf_size)) Loading @@ -785,12 +823,11 @@ ssize_t debugfs_write_file_bool(struct file *file, const char __user *user_buf, buf[buf_size] = '\0'; if (strtobool(buf, &bv) == 0) { r = debugfs_use_file_start(F_DENTRY(file), &srcu_idx); if (likely(!r)) *val = bv; debugfs_use_file_finish(srcu_idx); if (r) r = debugfs_file_get(dentry); if (unlikely(r)) return r; *val = bv; debugfs_file_put(dentry); } return count; Loading Loading @@ -852,14 +889,15 @@ 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; struct dentry *dentry = F_DENTRY(file); ssize_t r; int srcu_idx; r = debugfs_use_file_start(F_DENTRY(file), &srcu_idx); if (likely(!r)) r = debugfs_file_get(dentry); if (unlikely(r)) return r; r = simple_read_from_buffer(user_buf, count, ppos, blob->data, blob->size); debugfs_use_file_finish(srcu_idx); debugfs_file_put(dentry); return r; } Loading
fs/debugfs/inode.c +23 −6 Original line number Diff line number Diff line Loading @@ -374,6 +374,7 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode, inode->i_fop = proxy_fops; fsd->real_fops = real_fops; refcount_set(&fsd->active_users, 1); dentry->d_fsdata = fsd; d_instantiate(dentry, inode); Loading Loading @@ -631,18 +632,34 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, } EXPORT_SYMBOL_GPL(debugfs_create_symlink); static void __debugfs_remove_file(struct dentry *dentry, struct dentry *parent) { struct debugfs_fsdata *fsd; simple_unlink(d_inode(parent), dentry); d_delete(dentry); fsd = dentry->d_fsdata; init_completion(&fsd->active_users_drained); if (!refcount_dec_and_test(&fsd->active_users)) wait_for_completion(&fsd->active_users_drained); } static int __debugfs_remove(struct dentry *dentry, struct dentry *parent) { int ret = 0; if (simple_positive(dentry)) { dget(dentry); if (!d_is_reg(dentry)) { if (d_is_dir(dentry)) ret = simple_rmdir(d_inode(parent), dentry); else simple_unlink(d_inode(parent), dentry); if (!ret) d_delete(dentry); } else { __debugfs_remove_file(dentry, parent); } dput(dentry); } return ret; Loading
fs/debugfs/internal.h +2 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ extern const struct file_operations debugfs_full_proxy_file_operations; struct debugfs_fsdata { const struct file_operations *real_fops; refcount_t active_users; struct completion active_users_drained; }; #endif /* _DEBUGFS_INTERNAL_H_ */
include/linux/debugfs.h +12 −2 Original line number Diff line number Diff line Loading @@ -95,8 +95,10 @@ int debugfs_use_file_start(const struct dentry *dentry, int *srcu_idx) void debugfs_use_file_finish(int srcu_idx) __releases(&debugfs_srcu); const struct file_operations *debugfs_real_fops(const struct file *filp) __must_hold(&debugfs_srcu); const struct file_operations *debugfs_real_fops(const struct file *filp); int debugfs_file_get(struct dentry *dentry); void debugfs_file_put(struct dentry *dentry); ssize_t debugfs_attr_read(struct file *file, char __user *buf, size_t len, loff_t *ppos); Loading Loading @@ -236,6 +238,14 @@ static inline void debugfs_use_file_finish(int srcu_idx) __releases(&debugfs_srcu) { } static inline int debugfs_file_get(struct dentry *dentry) { return 0; } static inline void debugfs_file_put(struct dentry *dentry) { } static inline ssize_t debugfs_attr_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) { Loading