[PATCH 2/9] fuse2fs: rework checking file handles

Darrick J. Wong
2025-11-06T22:36:40Z

We only use FUSE2FS_CHECK_MAGIC for one thing -- to check the magic
number of file handles. Make the whole macro more specific to file
handles, and move it to the top of each function so that we don't take
locks or any other silly stuff like that.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
misc/fuse2fs.c | 43 +++++++++++++++++++++++++------------------
1 file changed, 25 insertions(+), 18 deletions(-)

diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c
index e973f75736a245..da37c095c7a304 100644
--- a/misc/fuse2fs.c
+++ b/misc/fuse2fs.c
@@ -248,9 +248,16 @@ struct fuse2fs {
#endif
};

-#define FUSE2FS_CHECK_MAGIC(fs, ptr, num) do {if ((ptr)->magic != (num)) \
- return translate_error((fs), 0, EXT2_ET_FILESYSTEM_CORRUPTED); \
-} while (0)
+#define FUSE2FS_CHECK_HANDLE(ff, fh) \
+ do { \
+ if ((fh) == NULL || (fh)->magic != FUSE2FS_FILE_MAGIC) { \
+ fprintf(stderr, \
+ "FUSE2FS: Corrupt in-memory file handle at %s:%d!\n", \
+ __func__, __LINE__); \
+ fflush(stderr); \
+ return -EUCLEAN; \
+ } \
+ } while (0)

#define __FUSE2FS_CHECK_CONTEXT(ff, retcode) \
do { \
@@ -3153,8 +3160,8 @@ static int op_read(const char *path EXT2FS_ATTR((unused)), char *buf,
int ret = 0;

FUSE2FS_CHECK_CONTEXT(ff);
+ FUSE2FS_CHECK_HANDLE(ff, fh);
fs = ff->fs;
- FUSE2FS_CHECK_MAGIC(fs, fh, FUSE2FS_FILE_MAGIC);
dbg_printf(ff, "%s: ino=%d off=%jd len=%jd\n", __func__, fh->ino,
(intmax_t) offset, len);
pthread_mutex_lock(&ff->bfl);
@@ -3210,8 +3217,8 @@ static int op_write(const char *path EXT2FS_ATTR((unused)),
int ret = 0;

FUSE2FS_CHECK_CONTEXT(ff);
+ FUSE2FS_CHECK_HANDLE(ff, fh);
fs = ff->fs;
- FUSE2FS_CHECK_MAGIC(fs, fh, FUSE2FS_FILE_MAGIC);
dbg_printf(ff, "%s: ino=%d off=%jd len=%jd\n", __func__, fh->ino,
(intmax_t) offset, (intmax_t) len);
pthread_mutex_lock(&ff->bfl);
@@ -3280,8 +3287,8 @@ static int op_release(const char *path EXT2FS_ATTR((unused)),
int ret = 0;

FUSE2FS_CHECK_CONTEXT(ff);
+ FUSE2FS_CHECK_HANDLE(ff, fh);
fs = ff->fs;
- FUSE2FS_CHECK_MAGIC(fs, fh, FUSE2FS_FILE_MAGIC);
dbg_printf(ff, "%s: ino=%d\n", __func__, fh->ino);
pthread_mutex_lock(&ff->bfl);

@@ -3314,8 +3321,8 @@ static int op_fsync(const char *path EXT2FS_ATTR((unused)),
int ret = 0;

FUSE2FS_CHECK_CONTEXT(ff);
+ FUSE2FS_CHECK_HANDLE(ff, fh);
fs = ff->fs;
- FUSE2FS_CHECK_MAGIC(fs, fh, FUSE2FS_FILE_MAGIC);
dbg_printf(ff, "%s: ino=%d\n", __func__, fh->ino);
/* For now, flush everything, even if it's slow */
pthread_mutex_lock(&ff->bfl);
@@ -3856,8 +3863,8 @@ static int op_readdir(const char *path EXT2FS_ATTR((unused)),
int ret = 0;

FUSE2FS_CHECK_CONTEXT(ff);
+ FUSE2FS_CHECK_HANDLE(ff, fh);
i.fs = ff->fs;
- FUSE2FS_CHECK_MAGIC(i.fs, fh, FUSE2FS_FILE_MAGIC);
dbg_printf(ff, "%s: ino=%d offset=%llu\n", __func__, fh->ino,
(unsigned long long)offset);
pthread_mutex_lock(&ff->bfl);
@@ -4052,8 +4059,8 @@ static int op_ftruncate(const char *path EXT2FS_ATTR((unused)),
int ret = 0;

FUSE2FS_CHECK_CONTEXT(ff);
+ FUSE2FS_CHECK_HANDLE(ff, fh);
fs = ff->fs;
- FUSE2FS_CHECK_MAGIC(fs, fh, FUSE2FS_FILE_MAGIC);
dbg_printf(ff, "%s: ino=%d len=%jd\n", __func__, fh->ino,
(intmax_t) len);
pthread_mutex_lock(&ff->bfl);
@@ -4104,8 +4111,8 @@ static int op_fgetattr(const char *path EXT2FS_ATTR((unused)),
int ret = 0;

FUSE2FS_CHECK_CONTEXT(ff);
+ FUSE2FS_CHECK_HANDLE(ff, fh);
fs = ff->fs;
- FUSE2FS_CHECK_MAGIC(fs, fh, FUSE2FS_FILE_MAGIC);
dbg_printf(ff, "%s: ino=%d\n", __func__, fh->ino);
pthread_mutex_lock(&ff->bfl);
ret = stat_inode(fs, fh->ino, statbuf);
@@ -4209,7 +4216,7 @@ static int ioctl_getflags(struct fuse2fs *ff, struct fuse2fs_file_handle *fh,
errcode_t err;
struct ext2_inode_large inode;

- FUSE2FS_CHECK_MAGIC(fs, fh, FUSE2FS_FILE_MAGIC);
+ FUSE2FS_CHECK_HANDLE(ff, fh);
dbg_printf(ff, "%s: ino=%d\n", __func__, fh->ino);
err = fuse2fs_read_inode(fs, fh->ino, &inode);
if (err)
@@ -4229,7 +4236,7 @@ static int ioctl_setflags(struct fuse2fs *ff, struct fuse2fs_file_handle *fh,
__u32 flags = *(__u32 *)data;
struct fuse_context *ctxt = fuse_get_context();

- FUSE2FS_CHECK_MAGIC(fs, fh, FUSE2FS_FILE_MAGIC);
+ FUSE2FS_CHECK_HANDLE(ff, fh);
dbg_printf(ff, "%s: ino=%d\n", __func__, fh->ino);
err = fuse2fs_read_inode(fs, fh->ino, &inode);
if (err)
@@ -4260,7 +4267,7 @@ static int ioctl_getversion(struct fuse2fs *ff, struct fuse2fs_file_handle *fh,
errcode_t err;
struct ext2_inode_large inode;

- FUSE2FS_CHECK_MAGIC(fs, fh, FUSE2FS_FILE_MAGIC);
+ FUSE2FS_CHECK_HANDLE(ff, fh);
dbg_printf(ff, "%s: ino=%d\n", __func__, fh->ino);
err = fuse2fs_read_inode(fs, fh->ino, &inode);
if (err)
@@ -4280,7 +4287,7 @@ static int ioctl_setversion(struct fuse2fs *ff, struct fuse2fs_file_handle *fh,
__u32 generation = *(__u32 *)data;
struct fuse_context *ctxt = fuse_get_context();

- FUSE2FS_CHECK_MAGIC(fs, fh, FUSE2FS_FILE_MAGIC);
+ FUSE2FS_CHECK_HANDLE(ff, fh);
dbg_printf(ff, "%s: ino=%d\n", __func__, fh->ino);
err = fuse2fs_read_inode(fs, fh->ino, &inode);
if (err)
@@ -4334,7 +4341,7 @@ static int ioctl_fsgetxattr(struct fuse2fs *ff, struct fuse2fs_file_handle *fh,
struct fsxattr *fsx = data;
unsigned int inode_size;

- FUSE2FS_CHECK_MAGIC(fs, fh, FUSE2FS_FILE_MAGIC);
+ FUSE2FS_CHECK_HANDLE(ff, fh);
dbg_printf(ff, "%s: ino=%d\n", __func__, fh->ino);
err = fuse2fs_read_inode(fs, fh->ino, &inode);
if (err)
@@ -4407,7 +4414,7 @@ static int ioctl_fssetxattr(struct fuse2fs *ff, struct fuse2fs_file_handle *fh,
struct fsxattr *fsx = data;
unsigned int inode_size;

- FUSE2FS_CHECK_MAGIC(fs, fh, FUSE2FS_FILE_MAGIC);
+ FUSE2FS_CHECK_HANDLE(ff, fh);
dbg_printf(ff, "%s: ino=%d\n", __func__, fh->ino);
err = fuse2fs_read_inode(fs, fh->ino, &inode);
if (err)
@@ -4637,8 +4644,8 @@ static int fallocate_helper(struct fuse_file_info *fp, int mode, off_t offset,
int flags;

FUSE2FS_CHECK_CONTEXT(ff);
+ FUSE2FS_CHECK_HANDLE(ff, fh);
fs = ff->fs;
- FUSE2FS_CHECK_MAGIC(fs, fh, FUSE2FS_FILE_MAGIC);
start = FUSE2FS_B_TO_FSBT(ff, offset);
end = FUSE2FS_B_TO_FSBT(ff, offset + len - 1);
dbg_printf(ff, "%s: ino=%d mode=0x%x start=%llu end=%llu\n", __func__,
@@ -4771,8 +4778,8 @@ static int punch_helper(struct fuse_file_info *fp, int mode, off_t offset,
char *buf = NULL;

FUSE2FS_CHECK_CONTEXT(ff);
+ FUSE2FS_CHECK_HANDLE(ff, fh);
fs = ff->fs;
- FUSE2FS_CHECK_MAGIC(fs, fh, FUSE2FS_FILE_MAGIC);
dbg_printf(ff, "%s: offset=%jd len=%jd\n", __func__,
(intmax_t) offset, (intmax_t) len);