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 > >