[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <175797570157.246189.18172211884520016217.stgit@frogsfrogsfrogs>
Date: Mon, 15 Sep 2025 15:42:55 -0700
From: "Darrick J. Wong" <djwong@...nel.org>
To: tytso@....edu
Cc: linux-ext4@...r.kernel.org
Subject: [PATCH 08/11] fuse2fs: improve want_extra_isize handling
From: Darrick J. Wong <djwong@...nel.org>
System administrators can set the {min,want}_extra_isize fields in the
superblock to try to influence the allocation of extra space in an
inode. Currently fuse2fs ignores any such value and sets it to the
minimum possible size; let's actually follow it, like the kernel does.
Note: fuse2fs isn't quite as flexible as the kernel is about changing
extra_isize, so this isn't quite good enough to pass ext4/022.
Signed-off-by: "Darrick J. Wong" <djwong@...nel.org>
---
misc/fuse2fs.c | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c
index 5409b288a025cf..f4ae7a273a83f5 100644
--- a/misc/fuse2fs.c
+++ b/misc/fuse2fs.c
@@ -1323,6 +1323,27 @@ static inline int fuse2fs_dirsync_flush(struct fuse2fs *ff, ext2_ino_t ino,
return 0;
}
+static void fuse2fs_set_extra_isize(struct fuse2fs *ff, ext2_ino_t ino,
+ struct ext2_inode_large *inode)
+{
+ ext2_filsys fs = ff->fs;
+ size_t extra = sizeof(struct ext2_inode_large) -
+ EXT2_GOOD_OLD_INODE_SIZE;
+
+ if (ext2fs_has_feature_extra_isize(fs->super)) {
+ dbg_printf(ff, "%s: ino=%u extra=%zu want=%u min=%u\n",
+ __func__, ino, extra, fs->super->s_want_extra_isize,
+ fs->super->s_min_extra_isize);
+
+ if (fs->super->s_want_extra_isize > extra)
+ extra = fs->super->s_want_extra_isize;
+ if (fs->super->s_min_extra_isize > extra)
+ extra = fs->super->s_min_extra_isize;
+ }
+
+ inode->i_extra_isize = extra;
+}
+
static int op_mknod(const char *path, mode_t mode, dev_t dev)
{
struct fuse_context *ctxt = fuse_get_context();
@@ -1418,8 +1439,7 @@ static int op_mknod(const char *path, mode_t mode, dev_t dev)
else
inode.i_block[0] = dev;
inode.i_links_count = 1;
- inode.i_extra_isize = sizeof(struct ext2_inode_large) -
- EXT2_GOOD_OLD_INODE_SIZE;
+ fuse2fs_set_extra_isize(ff, child, &inode);
fuse2fs_set_uid(&inode, ctxt->uid);
fuse2fs_set_gid(&inode, gid);
@@ -1537,6 +1557,7 @@ static int op_mkdir(const char *path, mode_t mode)
goto out2;
}
+ fuse2fs_set_extra_isize(ff, child, &inode);
fuse2fs_set_uid(&inode, ctxt->uid);
fuse2fs_set_gid(&inode, gid);
inode.i_mode = LINUX_S_IFDIR | (mode & ~S_ISUID);
@@ -1999,6 +2020,7 @@ static int op_symlink(const char *src, const char *dest)
goto out2;
}
+ fuse2fs_set_extra_isize(ff, child, &inode);
fuse2fs_set_uid(&inode, ctxt->uid);
fuse2fs_set_gid(&inode, gid);
inode.i_generation = ff->next_generation++;
@@ -3680,8 +3702,7 @@ static int op_create(const char *path, mode_t mode, struct fuse_file_info *fp)
memset(&inode, 0, sizeof(inode));
inode.i_mode = mode;
inode.i_links_count = 1;
- inode.i_extra_isize = sizeof(struct ext2_inode_large) -
- EXT2_GOOD_OLD_INODE_SIZE;
+ fuse2fs_set_extra_isize(ff, child, &inode);
fuse2fs_set_uid(&inode, ctxt->uid);
fuse2fs_set_gid(&inode, gid);
if (ext2fs_has_feature_extents(fs->super)) {
Powered by blists - more mailing lists