This allows fuse servers to pass in at mount time the blocksize that should be used for its inodes. Previously this was only supported for fuseblk servers and non-fuseblk servers could only specify blocksize dynamically through server replies (which is now disallowed). This gives a way for non-fuseblk fuse servers to specify the blocksize. The block size must be a power of 2 and >= FUSE_DEFAULT_BLKSIZE (which is also already a requirement for fuseblk servers). If the blocksize option is not set, the blocksize will be the default value (FUSE_DEFAULT_BLKSIZE for fuseblk servers and PAGE_SIZE for non-fuseblk servers). Signed-off-by: Joanne Koong <joannelkoong@xxxxxxxxx> --- fs/fuse/inode.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 280896d4fd44..23ebc59d0825 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -871,8 +871,9 @@ static int fuse_parse_param(struct fs_context *fsc, struct fs_parameter *param) break; case OPT_BLKSIZE: - if (!ctx->is_bdev) - return invalfc(fsc, "blksize only supported for fuseblk"); + if (result.uint_32 < FUSE_DEFAULT_BLKSIZE || + !is_power_of_2(result.uint_32)) + return invalfc(fsc, "Invalid blksize"); ctx->blksize = result.uint_32; break; @@ -1806,8 +1807,8 @@ int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx) goto err; #endif } else { - sb->s_blocksize = PAGE_SIZE; - sb->s_blocksize_bits = PAGE_SHIFT; + sb->s_blocksize = ctx->blksize; + sb->s_blocksize_bits = ilog2(sb->s_blocksize); } sb->s_subtype = ctx->subtype; @@ -2007,7 +2008,6 @@ static int fuse_init_fs_context(struct fs_context *fsc) return -ENOMEM; ctx->max_read = ~0; - ctx->blksize = FUSE_DEFAULT_BLKSIZE; ctx->legacy_opts_show = true; #ifdef CONFIG_BLOCK @@ -2017,6 +2017,8 @@ static int fuse_init_fs_context(struct fs_context *fsc) } #endif + ctx->blksize = ctx->is_bdev ? FUSE_DEFAULT_BLKSIZE : PAGE_SIZE; + fsc->fs_private = ctx; fsc->ops = &fuse_context_ops; return 0; -- 2.47.3