]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
fuse_ctl: use simple_recursive_removal()
authorAl Viro <viro@zeniv.linux.org.uk>
Mon, 10 Mar 2025 04:39:02 +0000 (00:39 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 3 Jul 2025 02:36:52 +0000 (22:36 -0400)
easier that way - no need to keep that array of dentry references, etc.

Reviewed-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/fuse/control.c
fs/fuse/fuse_i.h

index 2a730d88cc3bdb50ea1f8a3185faad5f05fc6e74..bb407705603c295159692e75599bf5289e1e5ea7 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/fs_context.h>
+#include <linux/namei.h>
 
 #define FUSE_CTL_SUPER_MAGIC 0x65735543
 
@@ -212,7 +213,6 @@ static struct dentry *fuse_ctl_add_dentry(struct dentry *parent,
        struct dentry *dentry;
        struct inode *inode;
 
-       BUG_ON(fc->ctl_ndents >= FUSE_CTL_NUM_DENTRIES);
        dentry = d_alloc_name(parent, name);
        if (!dentry)
                return NULL;
@@ -236,8 +236,6 @@ static struct dentry *fuse_ctl_add_dentry(struct dentry *parent,
        inode->i_private = fc;
        d_add(dentry, inode);
 
-       fc->ctl_dentry[fc->ctl_ndents++] = dentry;
-
        return dentry;
 }
 
@@ -280,27 +278,29 @@ int fuse_ctl_add_conn(struct fuse_conn *fc)
        return -ENOMEM;
 }
 
+static void remove_one(struct dentry *dentry)
+{
+       d_inode(dentry)->i_private = NULL;
+}
+
 /*
  * Remove a connection from the control filesystem (if it exists).
  * Caller must hold fuse_mutex
  */
 void fuse_ctl_remove_conn(struct fuse_conn *fc)
 {
-       int i;
+       struct dentry *dentry;
+       char name[32];
 
        if (!fuse_control_sb || fc->no_control)
                return;
 
-       for (i = fc->ctl_ndents - 1; i >= 0; i--) {
-               struct dentry *dentry = fc->ctl_dentry[i];
-               d_inode(dentry)->i_private = NULL;
-               if (!i) {
-                       /* Get rid of submounts: */
-                       d_invalidate(dentry);
-               }
-               dput(dentry);
+       sprintf(name, "%u", fc->dev);
+       dentry = lookup_noperm_positive_unlocked(&QSTR(name), fuse_control_sb->s_root);
+       if (!IS_ERR(dentry)) {
+               simple_recursive_removal(dentry, remove_one);
+               dput(dentry);   // paired with lookup_noperm_positive_unlocked()
        }
-       drop_nlink(d_inode(fuse_control_sb->s_root));
 }
 
 static int fuse_ctl_fill_super(struct super_block *sb, struct fs_context *fsc)
@@ -346,12 +346,8 @@ static int fuse_ctl_init_fs_context(struct fs_context *fsc)
 
 static void fuse_ctl_kill_sb(struct super_block *sb)
 {
-       struct fuse_conn *fc;
-
        mutex_lock(&fuse_mutex);
        fuse_control_sb = NULL;
-       list_for_each_entry(fc, &fuse_conn_list, entry)
-               fc->ctl_ndents = 0;
        mutex_unlock(&fuse_mutex);
 
        kill_litter_super(sb);
index b54f4f57789f7f369a8a9505c1c9dcfc53c71cd1..30206605e11489cf6c887f1a9128f2fb53bbaadc 100644 (file)
@@ -913,12 +913,6 @@ struct fuse_conn {
        /** Device ID from the root super block */
        dev_t dev;
 
-       /** Dentries in the control filesystem */
-       struct dentry *ctl_dentry[FUSE_CTL_NUM_DENTRIES];
-
-       /** number of dentries used in the above array */
-       int ctl_ndents;
-
        /** Key for lock owner ID scrambling */
        u32 scramble_key[4];