linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 0/2] fuse: disallow dynamic inode blksize changes
@ 2025-08-04 21:07 Joanne Koong
  2025-08-04 21:07 ` [PATCH v1 1/2] " Joanne Koong
  2025-08-04 21:07 ` [PATCH v1 2/2] fuse: add blksize configuration at mount for non-fuseblk servers Joanne Koong
  0 siblings, 2 replies; 5+ messages in thread
From: Joanne Koong @ 2025-08-04 21:07 UTC (permalink / raw)
  To: miklos; +Cc: djwong, willy, linux-fsdevel, kernel-team

With fuse now using iomap for writeback handling, inode blocksize changes are
problematic because iomap relies on the inode blocksize value for its internal
bitmap logic.

There are a few options for addressing this, as discussed in [1].
a) add "u8 blkbits" to iomap internals (struct iomap_folio_state) and change
iomap logic to use this static value instead of using inode->i_blkbits
b) remove all folios for the inode from the page cache and synchronize that
with modifying inode->i_blkbits
(unfortunately this does not work, see [1] for more details)
c) disallow the inode blocksize from changing dynamically in fuse

In the discussion in [1], we decided to go with c) given that servers don't
have a good use case for dynamically modifying the blocksize and it doesn't
seem likely that servers use this. If the server wishes to set a constant
blocksize for all inodes, then from patch 2, this can be done at mount time
through the -oblksize= configuration option.


Thanks,
Joanne

[1] https://lore.kernel.org/linux-fsdevel/CAJnrk1ZREcrd=FNUYLVWwXUeJ3mJz9J+aqyEvoHkyG3RrJ2QkA@mail.gmail.com/T/#m13c375821fb36c491626a59b552ed0cc5061736a

Joanne Koong (2):
  fuse: disallow dynamic inode blksize changes
  fuse: add blksize configuration at mount for non-fuseblk servers

 fs/fuse/dir.c             |  9 +--------
 fs/fuse/inode.c           | 18 +++++++++---------
 include/uapi/linux/fuse.h |  4 ++--
 3 files changed, 12 insertions(+), 19 deletions(-)

-- 
2.47.3


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v1 1/2] fuse: disallow dynamic inode blksize changes
  2025-08-04 21:07 [PATCH v1 0/2] fuse: disallow dynamic inode blksize changes Joanne Koong
@ 2025-08-04 21:07 ` Joanne Koong
  2025-08-05  5:11   ` Miklos Szeredi
  2025-08-04 21:07 ` [PATCH v1 2/2] fuse: add blksize configuration at mount for non-fuseblk servers Joanne Koong
  1 sibling, 1 reply; 5+ messages in thread
From: Joanne Koong @ 2025-08-04 21:07 UTC (permalink / raw)
  To: miklos; +Cc: djwong, willy, linux-fsdevel, kernel-team

With fuse using iomap, which relies on inode->i_blkbits for its internal
bitmap tracking, disallow fuse servers from dynamically changing the
inode blocksize.

"attr->blksize = sx->blksize;" is retained in fuse_statx_to_attr() so
that any attempts by the server to change the blksize through the statx
reply is surfaced to dmesg.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Fixes: ef7e7cbb32 ("fuse: use iomap for writeback")
---
 fs/fuse/dir.c             | 9 +--------
 fs/fuse/inode.c           | 6 ++----
 include/uapi/linux/fuse.h | 4 ++--
 3 files changed, 5 insertions(+), 14 deletions(-)

diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 45b4c3cc1396..df8fda289c5f 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1180,7 +1180,6 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
 static void fuse_fillattr(struct mnt_idmap *idmap, struct inode *inode,
 			  struct fuse_attr *attr, struct kstat *stat)
 {
-	unsigned int blkbits;
 	struct fuse_conn *fc = get_fuse_conn(inode);
 	vfsuid_t vfsuid = make_vfsuid(idmap, fc->user_ns,
 				      make_kuid(fc->user_ns, attr->uid));
@@ -1202,13 +1201,7 @@ static void fuse_fillattr(struct mnt_idmap *idmap, struct inode *inode,
 	stat->ctime.tv_nsec = attr->ctimensec;
 	stat->size = attr->size;
 	stat->blocks = attr->blocks;
-
-	if (attr->blksize != 0)
-		blkbits = ilog2(attr->blksize);
-	else
-		blkbits = inode->i_sb->s_blocksize_bits;
-
-	stat->blksize = 1 << blkbits;
+	stat->blksize = 1 << inode->i_sb->s_blocksize_bits;
 }
 
 static void fuse_statx_to_attr(struct fuse_statx *sx, struct fuse_attr *attr)
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index bfe8d8af46f3..280896d4fd44 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -285,10 +285,8 @@ void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
 		}
 	}
 
-	if (attr->blksize != 0)
-		inode->i_blkbits = ilog2(attr->blksize);
-	else
-		inode->i_blkbits = inode->i_sb->s_blocksize_bits;
+	if (attr->blksize && attr->blksize != inode->i_sb->s_blocksize)
+		pr_warn_ratelimited("changing blksize attribute is a no-op\n");
 
 	/*
 	 * Don't set the sticky bit in i_mode, unless we want the VFS
diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h
index 122d6586e8d4..4ceb6f736f4e 100644
--- a/include/uapi/linux/fuse.h
+++ b/include/uapi/linux/fuse.h
@@ -293,7 +293,7 @@ struct fuse_attr {
 	uint32_t	uid;
 	uint32_t	gid;
 	uint32_t	rdev;
-	uint32_t	blksize;
+	uint32_t	blksize; /* not used */
 	uint32_t	flags;
 };
 
@@ -309,7 +309,7 @@ struct fuse_sx_time {
 
 struct fuse_statx {
 	uint32_t	mask;
-	uint32_t	blksize;
+	uint32_t	blksize; /* not used */
 	uint64_t	attributes;
 	uint32_t	nlink;
 	uint32_t	uid;
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v1 2/2] fuse: add blksize configuration at mount for non-fuseblk servers
  2025-08-04 21:07 [PATCH v1 0/2] fuse: disallow dynamic inode blksize changes Joanne Koong
  2025-08-04 21:07 ` [PATCH v1 1/2] " Joanne Koong
@ 2025-08-04 21:07 ` Joanne Koong
  1 sibling, 0 replies; 5+ messages in thread
From: Joanne Koong @ 2025-08-04 21:07 UTC (permalink / raw)
  To: miklos; +Cc: djwong, willy, linux-fsdevel, kernel-team

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@gmail.com>
---
 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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v1 1/2] fuse: disallow dynamic inode blksize changes
  2025-08-04 21:07 ` [PATCH v1 1/2] " Joanne Koong
@ 2025-08-05  5:11   ` Miklos Szeredi
  2025-08-05 20:40     ` Joanne Koong
  0 siblings, 1 reply; 5+ messages in thread
From: Miklos Szeredi @ 2025-08-05  5:11 UTC (permalink / raw)
  To: Joanne Koong; +Cc: djwong, willy, linux-fsdevel, kernel-team

On Mon, 4 Aug 2025 at 23:10, Joanne Koong <joannelkoong@gmail.com> wrote:
>
> With fuse using iomap, which relies on inode->i_blkbits for its internal
> bitmap tracking, disallow fuse servers from dynamically changing the
> inode blocksize.
>
> "attr->blksize = sx->blksize;" is retained in fuse_statx_to_attr() so
> that any attempts by the server to change the blksize through the statx
> reply is surfaced to dmesg.

I expect no big breakage, but I'm quite sure that message will scare
some people for no good reason.  I'd just keep a copy of attr->blksize
in fuse_inode and present that in stx_blksize, while keeping the
internal i_blkbits consistent.

Thoughts?

Thanks,
Miklos

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v1 1/2] fuse: disallow dynamic inode blksize changes
  2025-08-05  5:11   ` Miklos Szeredi
@ 2025-08-05 20:40     ` Joanne Koong
  0 siblings, 0 replies; 5+ messages in thread
From: Joanne Koong @ 2025-08-05 20:40 UTC (permalink / raw)
  To: Miklos Szeredi; +Cc: djwong, willy, linux-fsdevel, kernel-team

On Mon, Aug 4, 2025 at 10:11 PM Miklos Szeredi <miklos@szeredi.hu> wrote:
>
> On Mon, 4 Aug 2025 at 23:10, Joanne Koong <joannelkoong@gmail.com> wrote:
> >
> > With fuse using iomap, which relies on inode->i_blkbits for its internal
> > bitmap tracking, disallow fuse servers from dynamically changing the
> > inode blocksize.
> >
> > "attr->blksize = sx->blksize;" is retained in fuse_statx_to_attr() so
> > that any attempts by the server to change the blksize through the statx
> > reply is surfaced to dmesg.
>
> I expect no big breakage, but I'm quite sure that message will scare
> some people for no good reason.  I'd just keep a copy of attr->blksize
> in fuse_inode and present that in stx_blksize, while keeping the
> internal i_blkbits consistent.
>
> Thoughts?

That sounds great and will make things simpler. We don't need the 2nd
patch then, I'll drop that in v2.

Thanks,
Joanne
>
> Thanks,
> Miklos

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2025-08-05 20:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-04 21:07 [PATCH v1 0/2] fuse: disallow dynamic inode blksize changes Joanne Koong
2025-08-04 21:07 ` [PATCH v1 1/2] " Joanne Koong
2025-08-05  5:11   ` Miklos Szeredi
2025-08-05 20:40     ` Joanne Koong
2025-08-04 21:07 ` [PATCH v1 2/2] fuse: add blksize configuration at mount for non-fuseblk servers Joanne Koong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).