[PATCH v1 1/2] fuse: disallow dynamic inode blksize changes

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

 



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





[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