Re: [PATCH v2 1/2] fuse: reflect cached blocksize if blocksize was changed

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Aug 13, 2025 at 03:35:20PM -0700, Joanne Koong wrote:
> As pointed out by Miklos[1], in the fuse_update_get_attr() path, the
> attributes returned to stat may be cached values instead of fresh ones
> fetched from the server. In the case where the server returned a
> modified blocksize value, we need to cache it and reflect it back to
> stat if values are not re-fetched since we now no longer directly change
> inode->i_blkbits.
> 
> Link: https://lore.kernel.org/linux-fsdevel/CAJfpeguCOxeVX88_zPd1hqziB_C+tmfuDhZP5qO2nKmnb-dTUA@xxxxxxxxxxxxxx/ [1]
> 
> Signed-off-by: Joanne Koong <joannelkoong@xxxxxxxxx>
> Fixes: 542ede096e48 ("fuse: keep inode->i_blkbits constant)
> ---
>  fs/fuse/dir.c    | 1 +
>  fs/fuse/fuse_i.h | 6 ++++++
>  fs/fuse/inode.c  | 5 +++++
>  3 files changed, 12 insertions(+)
> 
> diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
> index 2d817d7cab26..ebee7e0b1cd3 100644
> --- a/fs/fuse/dir.c
> +++ b/fs/fuse/dir.c
> @@ -1377,6 +1377,7 @@ static int fuse_update_get_attr(struct mnt_idmap *idmap, struct inode *inode,
>  		generic_fillattr(idmap, request_mask, inode, stat);
>  		stat->mode = fi->orig_i_mode;
>  		stat->ino = fi->orig_ino;
> +		stat->blksize = 1 << fi->cached_i_blkbits;
>  		if (test_bit(FUSE_I_BTIME, &fi->state)) {
>  			stat->btime = fi->i_btime;
>  			stat->result_mask |= STATX_BTIME;
> diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
> index ec248d13c8bf..db44d05c8d02 100644
> --- a/fs/fuse/fuse_i.h
> +++ b/fs/fuse/fuse_i.h
> @@ -210,6 +210,12 @@ struct fuse_inode {
>  	/** Reference to backing file in passthrough mode */
>  	struct fuse_backing *fb;
>  #endif
> +
> +	/*
> +	 * The underlying inode->i_blkbits value will not be modified,
> +	 * so preserve the blocksize specified by the server.
> +	 */
> +	unsigned char cached_i_blkbits;

Ahh, thanks for the comment.  That'll help me keep all this straight
later. :)
Reviewed-by: "Darrick J. Wong" <djwong@xxxxxxxxxx>

--D

>  };
>  
>  /** FUSE inode state bits */
> diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
> index 67c2318bfc42..3bfd83469d9f 100644
> --- a/fs/fuse/inode.c
> +++ b/fs/fuse/inode.c
> @@ -289,6 +289,11 @@ 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 = inode->i_sb->s_blocksize_bits;
> +
>  	/*
>  	 * Don't set the sticky bit in i_mode, unless we want the VFS
>  	 * to check permissions.  This prevents failures due to the
> -- 
> 2.47.3
> 
> 




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux