]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
functionfs: switch to simple_remove_by_name()
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 18 Sep 2025 02:55:33 +0000 (22:55 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 18 Nov 2025 04:57:39 +0000 (23:57 -0500)
No need to return dentry from ffs_sb_create_file() or keep it around
afterwards.

To avoid subtle issues with getting to ffs from epfiles in
ffs_epfiles_destroy(), pass the superblock as explicit argument.
Callers have it anyway.

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
drivers/usb/gadget/function/f_fs.c

index c7cb23a15fd08c29d3e77235ed9f2e03ebe0451d..40868ceb765c71747bfaa66b5bf2c0ac10c7ad28 100644 (file)
@@ -160,8 +160,6 @@ struct ffs_epfile {
        struct ffs_data                 *ffs;
        struct ffs_ep                   *ep;    /* P: ffs->eps_lock */
 
-       struct dentry                   *dentry;
-
        /*
         * Buffer for holding data from partial reads which may happen since
         * we’re rounding user read requests to a multiple of a max packet size.
@@ -271,11 +269,11 @@ struct ffs_desc_helper {
 };
 
 static int  __must_check ffs_epfiles_create(struct ffs_data *ffs);
-static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count);
+static void ffs_epfiles_destroy(struct super_block *sb,
+                               struct ffs_epfile *epfiles, unsigned count);
 
-static struct dentry *
-ffs_sb_create_file(struct super_block *sb, const char *name, void *data,
-                  const struct file_operations *fops);
+static int ffs_sb_create_file(struct super_block *sb, const char *name,
+                             void *data, const struct file_operations *fops);
 
 /* Devices management *******************************************************/
 
@@ -1894,9 +1892,8 @@ ffs_sb_make_inode(struct super_block *sb, void *data,
 }
 
 /* Create "regular" file */
-static struct dentry *ffs_sb_create_file(struct super_block *sb,
-                                       const char *name, void *data,
-                                       const struct file_operations *fops)
+static int ffs_sb_create_file(struct super_block *sb, const char *name,
+                             void *data, const struct file_operations *fops)
 {
        struct ffs_data *ffs = sb->s_fs_info;
        struct dentry   *dentry;
@@ -1904,16 +1901,16 @@ static struct dentry *ffs_sb_create_file(struct super_block *sb,
 
        dentry = d_alloc_name(sb->s_root, name);
        if (!dentry)
-               return NULL;
+               return -ENOMEM;
 
        inode = ffs_sb_make_inode(sb, data, fops, NULL, &ffs->file_perms);
        if (!inode) {
                dput(dentry);
-               return NULL;
+               return -ENOMEM;
        }
 
        d_add(dentry, inode);
-       return dentry;
+       return 0;
 }
 
 /* Super block */
@@ -1956,10 +1953,7 @@ static int ffs_sb_fill(struct super_block *sb, struct fs_context *fc)
                return -ENOMEM;
 
        /* EP0 file */
-       if (!ffs_sb_create_file(sb, "ep0", ffs, &ffs_ep0_operations))
-               return -ENOMEM;
-
-       return 0;
+       return ffs_sb_create_file(sb, "ep0", ffs, &ffs_ep0_operations);
 }
 
 enum {
@@ -2196,7 +2190,7 @@ static void ffs_data_closed(struct ffs_data *ffs)
                                                        flags);
 
                        if (epfiles)
-                               ffs_epfiles_destroy(epfiles,
+                               ffs_epfiles_destroy(ffs->sb, epfiles,
                                                 ffs->eps_count);
 
                        if (ffs->setup_state == FFS_SETUP_PENDING)
@@ -2255,7 +2249,7 @@ static void ffs_data_clear(struct ffs_data *ffs)
         * copy of epfile will save us from use-after-free.
         */
        if (epfiles) {
-               ffs_epfiles_destroy(epfiles, ffs->eps_count);
+               ffs_epfiles_destroy(ffs->sb, epfiles, ffs->eps_count);
                ffs->epfiles = NULL;
        }
 
@@ -2352,6 +2346,7 @@ static int ffs_epfiles_create(struct ffs_data *ffs)
 {
        struct ffs_epfile *epfile, *epfiles;
        unsigned i, count;
+       int err;
 
        count = ffs->eps_count;
        epfiles = kcalloc(count, sizeof(*epfiles), GFP_KERNEL);
@@ -2368,12 +2363,11 @@ static int ffs_epfiles_create(struct ffs_data *ffs)
                        sprintf(epfile->name, "ep%02x", ffs->eps_addrmap[i]);
                else
                        sprintf(epfile->name, "ep%u", i);
-               epfile->dentry = ffs_sb_create_file(ffs->sb, epfile->name,
-                                                epfile,
-                                                &ffs_epfile_operations);
-               if (!epfile->dentry) {
-                       ffs_epfiles_destroy(epfiles, i - 1);
-                       return -ENOMEM;
+               err = ffs_sb_create_file(ffs->sb, epfile->name,
+                                        epfile, &ffs_epfile_operations);
+               if (err) {
+                       ffs_epfiles_destroy(ffs->sb, epfiles, i - 1);
+                       return err;
                }
        }
 
@@ -2386,16 +2380,15 @@ static void clear_one(struct dentry *dentry)
        smp_store_release(&dentry->d_inode->i_private, NULL);
 }
 
-static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count)
+static void ffs_epfiles_destroy(struct super_block *sb,
+                               struct ffs_epfile *epfiles, unsigned count)
 {
        struct ffs_epfile *epfile = epfiles;
+       struct dentry *root = sb->s_root;
 
        for (; count; --count, ++epfile) {
                BUG_ON(mutex_is_locked(&epfile->mutex));
-               if (epfile->dentry) {
-                       simple_recursive_removal(epfile->dentry, clear_one);
-                       epfile->dentry = NULL;
-               }
+               simple_remove_by_name(root, epfile->name, clear_one);
        }
 
        kfree(epfiles);