]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
Revert "functionfs: fix the open/removal races"
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 21 Jan 2026 17:21:16 +0000 (18:21 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 23 Jan 2026 10:21:36 +0000 (11:21 +0100)
This reverts commit b49c766856fb5901490de577e046149ebf15e39d which is
commit e5bf5ee266633cb18fff6f98f0b7d59a62819eee upstream.

It has been reported to cause test problems in Android devices.  As the
other functionfs changes were not also backported at the same time,
something is out of sync.  So just revert this one for now and it can
come back in the future as a patch series if it is tested.

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

index 69f6e3c0f7e00df4d529ac2a154b09cd1c25dac6..47cfbe41fdff8dc2b662d2cf05c454c34096e7e5 100644 (file)
@@ -640,22 +640,13 @@ done_mutex:
 
 static int ffs_ep0_open(struct inode *inode, struct file *file)
 {
-       struct ffs_data *ffs = inode->i_sb->s_fs_info;
-       int ret;
+       struct ffs_data *ffs = inode->i_private;
 
-       /* Acquire mutex */
-       ret = ffs_mutex_lock(&ffs->mutex, file->f_flags & O_NONBLOCK);
-       if (ret < 0)
-               return ret;
-
-       ffs_data_opened(ffs);
-       if (ffs->state == FFS_CLOSING) {
-               ffs_data_closed(ffs);
-               mutex_unlock(&ffs->mutex);
+       if (ffs->state == FFS_CLOSING)
                return -EBUSY;
-       }
-       mutex_unlock(&ffs->mutex);
+
        file->private_data = ffs;
+       ffs_data_opened(ffs);
 
        return stream_open(inode, file);
 }
@@ -1202,33 +1193,14 @@ error:
 static int
 ffs_epfile_open(struct inode *inode, struct file *file)
 {
-       struct ffs_data *ffs = inode->i_sb->s_fs_info;
-       struct ffs_epfile *epfile;
-       int ret;
+       struct ffs_epfile *epfile = inode->i_private;
 
-       /* Acquire mutex */
-       ret = ffs_mutex_lock(&ffs->mutex, file->f_flags & O_NONBLOCK);
-       if (ret < 0)
-               return ret;
-
-       if (!atomic_inc_not_zero(&ffs->opened)) {
-               mutex_unlock(&ffs->mutex);
-               return -ENODEV;
-       }
-       /*
-        * we want the state to be FFS_ACTIVE; FFS_ACTIVE alone is
-        * not enough, though - we might have been through FFS_CLOSING
-        * and back to FFS_ACTIVE, with our file already removed.
-        */
-       epfile = smp_load_acquire(&inode->i_private);
-       if (unlikely(ffs->state != FFS_ACTIVE || !epfile)) {
-               mutex_unlock(&ffs->mutex);
-               ffs_data_closed(ffs);
+       if (WARN_ON(epfile->ffs->state != FFS_ACTIVE))
                return -ENODEV;
-       }
-       mutex_unlock(&ffs->mutex);
 
        file->private_data = epfile;
+       ffs_data_opened(epfile->ffs);
+
        return stream_open(inode, file);
 }
 
@@ -1360,7 +1332,7 @@ static void ffs_dmabuf_put(struct dma_buf_attachment *attach)
 static int
 ffs_epfile_release(struct inode *inode, struct file *file)
 {
-       struct ffs_epfile *epfile = file->private_data;
+       struct ffs_epfile *epfile = inode->i_private;
        struct ffs_dmabuf_priv *priv, *tmp;
        struct ffs_data *ffs = epfile->ffs;
 
@@ -2380,11 +2352,6 @@ static int ffs_epfiles_create(struct ffs_data *ffs)
        return 0;
 }
 
-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)
 {
        struct ffs_epfile *epfile = epfiles;
@@ -2392,7 +2359,7 @@ static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count)
        for (; count; --count, ++epfile) {
                BUG_ON(mutex_is_locked(&epfile->mutex));
                if (epfile->dentry) {
-                       simple_recursive_removal(epfile->dentry, clear_one);
+                       simple_recursive_removal(epfile->dentry, NULL);
                        epfile->dentry = NULL;
                }
        }