[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <175279461105.715479.3013611859177576387.stgit@frogsfrogsfrogs>
Date: Thu, 17 Jul 2025 16:40:24 -0700
From: "Darrick J. Wong" <djwong@...nel.org>
To: tytso@....edu
Cc: joannelkoong@...il.com, miklos@...redi.hu, John@...ves.net,
linux-fsdevel@...r.kernel.org, bernd@...ernd.com, linux-ext4@...r.kernel.org,
neal@...pa.dev
Subject: [PATCH 04/22] fuse2fs: register block devices for use with iomap
From: Darrick J. Wong <djwong@...nel.org>
Register the ext4 block device with the kernel for use with iomap. For
now this is redundant with using fuseblk mode because the kernel
automatically registers any fuseblk devices, but eventually we'll go
back to regular fuse mode and we'll have to pin the bdev ourselves.
In theory this interface supports strange beasts where the metadata can
exist somewhere else entirely (or be made up by AI) while the file data
persists to real disks.
Signed-off-by: "Darrick J. Wong" <djwong@...nel.org>
---
misc/fuse2fs.c | 45 +++++++++++++++++++++++++++++++++++++++++----
1 file changed, 41 insertions(+), 4 deletions(-)
diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c
index fb71886b58f215..9eb067e1737054 100644
--- a/misc/fuse2fs.c
+++ b/misc/fuse2fs.c
@@ -40,6 +40,7 @@
# define _FILE_OFFSET_BITS 64
#endif /* _FILE_OFFSET_BITS */
#include <fuse.h>
+#include <fuse_lowlevel.h>
#ifdef __SET_FOB_FOR_FUSE
# undef _FILE_OFFSET_BITS
#endif /* __SET_FOB_FOR_FUSE */
@@ -265,6 +266,7 @@ struct fuse2fs {
#ifdef HAVE_FUSE_IOMAP
enum fuse2fs_feature_toggle iomap_want;
enum fuse2fs_iomap_state iomap_state;
+ uint32_t iomap_dev;
#endif
unsigned int blockmask;
int retcode;
@@ -5032,7 +5034,7 @@ static errcode_t fuse2fs_iomap_begin_extent(struct fuse2fs *ff, uint64_t ino,
}
/* Mapping overlaps startoff, report this. */
- iomap->dev = FUSE_IOMAP_DEV_NULL;
+ iomap->dev = ff->iomap_dev;
iomap->addr = FUSE2FS_FSB_TO_B(ff, extent.e_pblk);
iomap->offset = FUSE2FS_FSB_TO_B(ff, extent.e_lblk);
iomap->length = FUSE2FS_FSB_TO_B(ff, extent.e_len);
@@ -5064,13 +5066,14 @@ static int fuse2fs_iomap_begin_indirect(struct fuse2fs *ff, uint64_t ino,
if (err)
return translate_error(fs, ino, err);
- iomap->dev = FUSE_IOMAP_DEV_NULL;
iomap->offset = pos;
iomap->flags |= FUSE_IOMAP_F_MERGED;
if (startblock) {
+ iomap->dev = ff->iomap_dev;
iomap->addr = FUSE2FS_FSB_TO_B(ff, startblock);
iomap->type = FUSE_IOMAP_TYPE_MAPPED;
} else {
+ iomap->dev = FUSE_IOMAP_DEV_NULL;
iomap->addr = FUSE_IOMAP_NULL_ADDR;
iomap->type = FUSE_IOMAP_TYPE_HOLE;
}
@@ -5275,12 +5278,38 @@ static off_t fuse2fs_max_size(struct fuse2fs *ff, off_t upper_limit)
return res;
}
+static errcode_t fuse2fs_iomap_config_devices(struct fuse_context *ctxt,
+ struct fuse2fs *ff)
+{
+ struct fuse_session *se = fuse_get_session(ctxt->fuse);
+ errcode_t err;
+ int fd;
+ int ret;
+
+ err = io_channel_fd(ff->fs->io, &fd);
+ if (err)
+ return err;
+
+ ret = fuse_iomap_add_device(se, fd, 0);
+
+ dbg_printf(ff, "%s: registering iomap dev fd=%d ret=%d iomap_dev=%u\n",
+ __func__, fd, ret, ff->iomap_dev);
+
+ if (ret < 1)
+ return -EIO;
+
+ ff->iomap_dev = ret;
+ return 0;
+}
+
static int op_iomap_config(uint32_t flags, off_t maxbytes,
struct fuse_iomap_config *cfg)
{
struct fuse_context *ctxt = fuse_get_context();
struct fuse2fs *ff = (struct fuse2fs *)ctxt->private_data;
ext2_filsys fs;
+ errcode_t err;
+ int ret = 0;
FUSE2FS_CHECK_CONTEXT(ff);
@@ -5314,8 +5343,15 @@ static int op_iomap_config(uint32_t flags, off_t maxbytes,
cfg->flags |= FUSE_IOMAP_CONFIG_MAXBYTES;
cfg->s_maxbytes = fuse2fs_max_size(ff, maxbytes);
- fuse2fs_finish(ff, 0);
- return 0;
+ err = fuse2fs_iomap_config_devices(ctxt, ff);
+ if (err) {
+ ret = translate_error(fs, 0, err);
+ goto out_unlock;
+ }
+
+out_unlock:
+ fuse2fs_finish(ff, ret);
+ return ret;
}
#endif /* HAVE_FUSE_IOMAP */
@@ -5633,6 +5669,7 @@ int main(int argc, char *argv[])
#ifdef HAVE_FUSE_IOMAP
.iomap_want = FT_DEFAULT,
.iomap_state = IOMAP_UNKNOWN,
+ .iomap_dev = FUSE_IOMAP_DEV_NULL,
#endif
};
errcode_t err;
Powered by blists - more mailing lists