]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
fuse: remove fc->blkbits workaround for partial writes
authorJoanne Koong <joannelkoong@gmail.com>
Fri, 26 Sep 2025 00:26:09 +0000 (17:26 -0700)
committerChristian Brauner <brauner@kernel.org>
Wed, 5 Nov 2025 11:57:24 +0000 (12:57 +0100)
Now that fuse is integrated with iomap for read/readahead, we can remove
the workaround that was added in commit bd24d2108e9c ("fuse: fix fuseblk
i_blkbits for iomap partial writes"), which was previously needed to
avoid a race condition where an iomap partial write may be overwritten
by a read if blocksize < PAGE_SIZE. Now that fuse does iomap
read/readahead, this is protected against since there is granular
uptodate tracking of blocks, which means this workaround can be removed.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Tested-by: syzbot@syzkaller.appspotmail.com
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/fuse/dir.c
fs/fuse/fuse_i.h
fs/fuse/inode.c

index ecaec0fea3a132e7cbb88121e7db7fb504d57d3c..316922d5dd131803c7e77f515e52590aba524a5c 100644 (file)
@@ -1192,7 +1192,7 @@ static void fuse_fillattr(struct mnt_idmap *idmap, struct inode *inode,
        if (attr->blksize != 0)
                blkbits = ilog2(attr->blksize);
        else
-               blkbits = fc->blkbits;
+               blkbits = inode->i_sb->s_blocksize_bits;
 
        stat->blksize = 1 << blkbits;
 }
index c2f2a48156d6c52c8db87a5c092f51d1627deae9..f616c1991fed9ccda0be1bd3dc8904ab29d5fd88 100644 (file)
@@ -981,14 +981,6 @@ struct fuse_conn {
                /* Request timeout (in jiffies). 0 = no timeout */
                unsigned int req_timeout;
        } timeout;
-
-       /*
-        * This is a workaround until fuse uses iomap for reads.
-        * For fuseblk servers, this represents the blocksize passed in at
-        * mount time and for regular fuse servers, this is equivalent to
-        * inode->i_blkbits.
-        */
-       u8 blkbits;
 };
 
 /*
index d1babf56f25470fcc08fe400467b3450e8b7464a..8ba29ca23244fc08e4d3358e15a6417fa48b7427 100644 (file)
@@ -291,7 +291,7 @@ void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
        if (attr->blksize)
                fi->cached_i_blkbits = ilog2(attr->blksize);
        else
-               fi->cached_i_blkbits = fc->blkbits;
+               fi->cached_i_blkbits = inode->i_sb->s_blocksize_bits;
 
        /*
         * Don't set the sticky bit in i_mode, unless we want the VFS
@@ -1838,22 +1838,11 @@ int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx)
                err = -EINVAL;
                if (!sb_set_blocksize(sb, ctx->blksize))
                        goto err;
-               /*
-                * This is a workaround until fuse hooks into iomap for reads.
-                * Use PAGE_SIZE for the blocksize else if the writeback cache
-                * is enabled, buffered writes go through iomap and a read may
-                * overwrite partially written data if blocksize < PAGE_SIZE
-                */
-               fc->blkbits = sb->s_blocksize_bits;
-               if (ctx->blksize != PAGE_SIZE &&
-                   !sb_set_blocksize(sb, PAGE_SIZE))
-                       goto err;
 #endif
                fc->sync_fs = 1;
        } else {
                sb->s_blocksize = PAGE_SIZE;
                sb->s_blocksize_bits = PAGE_SHIFT;
-               fc->blkbits = sb->s_blocksize_bits;
        }
 
        sb->s_subtype = ctx->subtype;