mirror of https://github.com/OpenIPC/firmware.git
137 lines
3.4 KiB
Diff
137 lines
3.4 KiB
Diff
diff -drupN a/fs/debugfs/inode.c b/fs/debugfs/inode.c
|
|
--- a/fs/debugfs/inode.c 2018-08-06 17:23:04.000000000 +0300
|
|
+++ b/fs/debugfs/inode.c 2022-06-12 05:28:14.000000000 +0300
|
|
@@ -27,14 +27,11 @@
|
|
#include <linux/parser.h>
|
|
#include <linux/magic.h>
|
|
#include <linux/slab.h>
|
|
-#include <linux/srcu.h>
|
|
|
|
#include "internal.h"
|
|
|
|
#define DEBUGFS_DEFAULT_MODE 0700
|
|
|
|
-DEFINE_SRCU(debugfs_srcu);
|
|
-
|
|
static struct vfsmount *debugfs_mount;
|
|
static int debugfs_mount_count;
|
|
static bool debugfs_registered;
|
|
@@ -185,6 +182,11 @@ static const struct super_operations deb
|
|
.evict_inode = debugfs_evict_inode,
|
|
};
|
|
|
|
+static void debugfs_release_dentry(struct dentry *dentry)
|
|
+{
|
|
+ kfree(dentry->d_fsdata);
|
|
+}
|
|
+
|
|
static struct vfsmount *debugfs_automount(struct path *path)
|
|
{
|
|
debugfs_automount_t f;
|
|
@@ -194,6 +196,7 @@ static struct vfsmount *debugfs_automoun
|
|
|
|
static const struct dentry_operations debugfs_dops = {
|
|
.d_delete = always_delete_dentry,
|
|
+ .d_release = debugfs_release_dentry,
|
|
.d_automount = debugfs_automount,
|
|
};
|
|
|
|
@@ -307,24 +310,35 @@ static struct dentry *__debugfs_create_f
|
|
{
|
|
struct dentry *dentry;
|
|
struct inode *inode;
|
|
+ struct debugfs_fsdata *fsd;
|
|
+
|
|
+ fsd = kmalloc(sizeof(*fsd), GFP_KERNEL);
|
|
+ if (!fsd)
|
|
+ return NULL;
|
|
|
|
if (!(mode & S_IFMT))
|
|
mode |= S_IFREG;
|
|
BUG_ON(!S_ISREG(mode));
|
|
dentry = start_creating(name, parent);
|
|
|
|
- if (IS_ERR(dentry))
|
|
+ if (IS_ERR(dentry)) {
|
|
+ kfree(fsd);
|
|
return NULL;
|
|
+ }
|
|
|
|
inode = debugfs_get_inode(dentry->d_sb);
|
|
- if (unlikely(!inode))
|
|
+ if (unlikely(!inode)) {
|
|
+ kfree(fsd);
|
|
return failed_creating(dentry);
|
|
+ }
|
|
|
|
inode->i_mode = mode;
|
|
inode->i_private = data;
|
|
|
|
inode->i_fop = proxy_fops;
|
|
- dentry->d_fsdata = (void *)real_fops;
|
|
+ fsd->real_fops = real_fops;
|
|
+ refcount_set(&fsd->active_users, 1);
|
|
+ dentry->d_fsdata = fsd;
|
|
|
|
d_instantiate(dentry, inode);
|
|
fsnotify_create(d_inode(dentry->d_parent), dentry);
|
|
@@ -581,18 +595,34 @@ struct dentry *debugfs_create_symlink(co
|
|
}
|
|
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_dir(dentry))
|
|
- ret = simple_rmdir(d_inode(parent), dentry);
|
|
- else
|
|
- simple_unlink(d_inode(parent), dentry);
|
|
- if (!ret)
|
|
- d_delete(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;
|
|
@@ -626,8 +656,6 @@ void debugfs_remove(struct dentry *dentr
|
|
inode_unlock(d_inode(parent));
|
|
if (!ret)
|
|
simple_release_fs(&debugfs_mount, &debugfs_mount_count);
|
|
-
|
|
- synchronize_srcu(&debugfs_srcu);
|
|
}
|
|
EXPORT_SYMBOL_GPL(debugfs_remove);
|
|
|
|
@@ -701,8 +729,6 @@ void debugfs_remove_recursive(struct den
|
|
if (!__debugfs_remove(child, parent))
|
|
simple_release_fs(&debugfs_mount, &debugfs_mount_count);
|
|
inode_unlock(d_inode(parent));
|
|
-
|
|
- synchronize_srcu(&debugfs_srcu);
|
|
}
|
|
EXPORT_SYMBOL_GPL(debugfs_remove_recursive);
|
|
|