From: "Darrick J. Wong" <djwong@kernel.org>
To: Joanne Koong <joannelkoong@gmail.com>
Cc: miklos@szeredi.hu, bernd@bsbernd.com, neal@gompa.dev,
linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH 10/31] fuse: implement basic iomap reporting such as FIEMAP and SEEK_{DATA,HOLE}
Date: Thu, 22 Jan 2026 14:31:19 -0800 [thread overview]
Message-ID: <20260122223119.GB5900@frogsfrogsfrogs> (raw)
In-Reply-To: <CAJnrk1Y8Fi7ZgY15WDtKZ1kVAsh-kzfNbEOvHKNwCxtA6iWzWA@mail.gmail.com>
On Wed, Jan 21, 2026 at 06:07:12PM -0800, Joanne Koong wrote:
> On Tue, Oct 28, 2025 at 5:47 PM Darrick J. Wong <djwong@kernel.org> wrote:
> >
> > From: Darrick J. Wong <djwong@kernel.org>
> >
> > Implement the basic file mapping reporting functions like FIEMAP, BMAP,
> > and SEEK_DATA/HOLE.
> >
> > Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> > ---
> > fs/fuse/fuse_i.h | 8 ++++++
> > fs/fuse/dir.c | 1 +
> > fs/fuse/file.c | 13 ++++++++++
> > fs/fuse/file_iomap.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++-
> > 4 files changed, 89 insertions(+), 1 deletion(-)
> >
> >
> > diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
> > index c7aeb324fe599e..6fe8aa1845b98d 100644
> > --- a/fs/fuse/fuse_i.h
> > +++ b/fs/fuse/fuse_i.h
> > @@ -1730,6 +1730,11 @@ static inline bool fuse_inode_has_iomap(const struct inode *inode)
> >
> > return test_bit(FUSE_I_IOMAP, &fi->state);
> > }
> > +
> > +int fuse_iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
> > + u64 start, u64 length);
> > +loff_t fuse_iomap_lseek(struct file *file, loff_t offset, int whence);
> > +sector_t fuse_iomap_bmap(struct address_space *mapping, sector_t block);
> > #else
> > # define fuse_iomap_enabled(...) (false)
> > # define fuse_has_iomap(...) (false)
> > @@ -1739,6 +1744,9 @@ static inline bool fuse_inode_has_iomap(const struct inode *inode)
> > # define fuse_iomap_init_nonreg_inode(...) ((void)0)
> > # define fuse_iomap_evict_inode(...) ((void)0)
> > # define fuse_inode_has_iomap(...) (false)
> > +# define fuse_iomap_fiemap NULL
> > +# define fuse_iomap_lseek(...) (-ENOSYS)
> > +# define fuse_iomap_bmap(...) (-ENOSYS)
> > #endif
> >
> > #endif /* _FS_FUSE_I_H */
> > diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
> > index 18eb1bb192bb58..bafc386f2f4d3a 100644
> > --- a/fs/fuse/dir.c
> > +++ b/fs/fuse/dir.c
> > @@ -2296,6 +2296,7 @@ static const struct inode_operations fuse_common_inode_operations = {
> > .set_acl = fuse_set_acl,
> > .fileattr_get = fuse_fileattr_get,
> > .fileattr_set = fuse_fileattr_set,
> > + .fiemap = fuse_iomap_fiemap,
> > };
> >
> > static const struct inode_operations fuse_symlink_inode_operations = {
> > diff --git a/fs/fuse/file.c b/fs/fuse/file.c
> > index bd9c208a46c78d..8a981f41b1dbd0 100644
> > --- a/fs/fuse/file.c
> > +++ b/fs/fuse/file.c
> > @@ -2512,6 +2512,12 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block)
> > struct fuse_bmap_out outarg;
> > int err;
> >
> > + if (fuse_inode_has_iomap(inode)) {
> > + sector_t alt_sec = fuse_iomap_bmap(mapping, block);
> > + if (alt_sec > 0)
> > + return alt_sec;
> > + }
> > +
> > if (!inode->i_sb->s_bdev || fm->fc->no_bmap)
> > return 0;
> >
> > @@ -2547,6 +2553,13 @@ static loff_t fuse_lseek(struct file *file, loff_t offset, int whence)
> > struct fuse_lseek_out outarg;
> > int err;
> >
> > + if (fuse_inode_has_iomap(inode)) {
> > + loff_t alt_pos = fuse_iomap_lseek(file, offset, whence);
> > +
> > + if (alt_pos >= 0 || (alt_pos < 0 && alt_pos != -ENOSYS))
>
> I don't think you technically need the "alt_pos < 0" part here since
> the "alt_pos >= 0 ||" part already accounts for that
alt_pos is loff_t, which is a signed type.
But I think this could be more concise:
alt_pos = fuse_iomap_lseek(...);
if (alt_pos != -ENOSYS)
return alt_pos;
> > + return alt_pos;
> > + }
> > +
> > if (fm->fc->no_lseek)
> > goto fallback;
> >
> > diff --git a/fs/fuse/file_iomap.c b/fs/fuse/file_iomap.c
> > index 66a7b8faa31ac2..ce64e7c4860ef8 100644
> > --- a/fs/fuse/file_iomap.c
> > +++ b/fs/fuse/file_iomap.c
> > @@ -4,6 +4,7 @@
> > * Author: Darrick J. Wong <djwong@kernel.org>
> > */
> > #include <linux/iomap.h>
> > +#include <linux/fiemap.h>
> > #include "fuse_i.h"
> > #include "fuse_trace.h"
> > #include "iomap_i.h"
> > @@ -561,7 +562,7 @@ static int fuse_iomap_end(struct inode *inode, loff_t pos, loff_t count,
> > return err;
> > }
> >
> > -const struct iomap_ops fuse_iomap_ops = {
> > +static const struct iomap_ops fuse_iomap_ops = {
> > .iomap_begin = fuse_iomap_begin,
> > .iomap_end = fuse_iomap_end,
> > };
> > @@ -690,3 +691,68 @@ void fuse_iomap_evict_inode(struct inode *inode)
> > if (conn->iomap && fuse_inode_is_exclusive(inode))
> > clear_bit(FUSE_I_EXCLUSIVE, &fi->state);
> > }
> > +
> > +int fuse_iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
> > + u64 start, u64 count)
> > +{
> > + struct fuse_conn *fc = get_fuse_conn(inode);
> > + int error;
> > +
> > + /*
> > + * We are called directly from the vfs so we need to check per-inode
> > + * support here explicitly.
> > + */
> > + if (!fuse_inode_has_iomap(inode))
> > + return -EOPNOTSUPP;
> > +
> > + if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR)
>
> I don't see where FIEMAP_FLAG_SYNC and FIEMAP_FLAG_CACHE are supported
> either, should these return -EOPNOTSUPP if they're set as well?
The vfs implements FIEMAP_FLAG_SYNC for us in fiemap_prep, which is
called by iomap_fiemap.
I'm not sure what FIEMAP_FLAG_CACHE means in this context. Its comment
says "request caching of the extents" which doesn't sound like doing
anything is mandatory.
> > + return -EOPNOTSUPP;
> > +
> > + if (fuse_is_bad(inode))
> > + return -EIO;
> > +
> > + if (!fuse_allow_current_process(fc))
> > + return -EACCES;
> > +
> > + inode_lock_shared(inode);
> > + error = iomap_fiemap(inode, fieinfo, start, count, &fuse_iomap_ops);
> > + inode_unlock_shared(inode);
> > +
> > + return error;
> > +}
> > +
> > +sector_t fuse_iomap_bmap(struct address_space *mapping, sector_t block)
> > +{
> > + ASSERT(fuse_inode_has_iomap(mapping->host));
> > +
> > + return iomap_bmap(mapping, block, &fuse_iomap_ops);
> > +}
> > +
> > +loff_t fuse_iomap_lseek(struct file *file, loff_t offset, int whence)
> > +{
> > + struct inode *inode = file->f_mapping->host;
> > + struct fuse_conn *fc = get_fuse_conn(inode);
> > +
> > + ASSERT(fuse_inode_has_iomap(inode));
> > +
> > + if (fuse_is_bad(inode))
> > + return -EIO;
> > +
> > + if (!fuse_allow_current_process(fc))
> > + return -EACCES;
> > +
> > + switch (whence) {
> > + case SEEK_HOLE:
> > + offset = iomap_seek_hole(inode, offset, &fuse_iomap_ops);
> > + break;
> > + case SEEK_DATA:
> > + offset = iomap_seek_data(inode, offset, &fuse_iomap_ops);
> > + break;
> > + default:
>
> Does it make sense to have the default case just call generic_file_llseek()?
Yes. Thanks for spotting that bug!
--D
> Thanks,
> Joanne
>
> > + return -ENOSYS;
> > + }
> > +
> > + if (offset < 0)
> > + return offset;
> > + return vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
> > +}
> >
>
next prev parent reply other threads:[~2026-01-22 22:31 UTC|newest]
Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20251029002755.GK6174@frogsfrogsfrogs>
[not found] ` <176169810144.1424854.11439355400009006946.stgit@frogsfrogsfrogs>
[not found] ` <176169810371.1424854.3010195280915622081.stgit@frogsfrogsfrogs>
2026-01-21 19:34 ` [PATCH 01/31] fuse: implement the basic iomap mechanisms Joanne Koong
2026-01-21 22:45 ` Darrick J. Wong
2026-01-22 0:06 ` Joanne Koong
2026-01-22 0:34 ` Darrick J. Wong
2026-02-05 19:22 ` Chris Mason
2026-02-05 23:31 ` Darrick J. Wong
[not found] ` <176169810415.1424854.10373764649459618752.stgit@frogsfrogsfrogs>
2026-01-21 23:42 ` [PATCH 03/31] fuse: make debugging configurable at runtime Joanne Koong
2026-01-22 0:02 ` Darrick J. Wong
2026-01-22 0:23 ` Joanne Koong
2026-01-22 0:40 ` Darrick J. Wong
[not found] ` <176169810502.1424854.13869957103489591272.stgit@frogsfrogsfrogs>
2026-01-22 1:13 ` [PATCH 07/31] fuse: create a per-inode flag for toggling iomap Joanne Koong
2026-01-22 22:22 ` Darrick J. Wong
2026-01-23 18:05 ` Joanne Koong
2026-01-24 16:54 ` Darrick J. Wong
2026-01-27 23:33 ` Darrick J. Wong
[not found] ` <176169810568.1424854.4073875923015322741.stgit@frogsfrogsfrogs>
2026-01-22 2:07 ` [PATCH 10/31] fuse: implement basic iomap reporting such as FIEMAP and SEEK_{DATA,HOLE} Joanne Koong
2026-01-22 22:31 ` Darrick J. Wong [this message]
[not found] ` <176169810700.1424854.5753715202341698632.stgit@frogsfrogsfrogs>
2026-01-23 21:50 ` [PATCH 16/31] fuse: implement large folios for iomap pagecache files Joanne Koong
[not found] ` <176169810721.1424854.6150447623894591900.stgit@frogsfrogsfrogs>
2026-01-26 22:03 ` [PATCH 17/31] fuse: use an unrestricted backing device with iomap pagecache io Joanne Koong
2026-01-26 23:55 ` Darrick J. Wong
2026-01-27 1:35 ` Joanne Koong
2026-01-27 2:09 ` Darrick J. Wong
2026-01-27 18:04 ` Joanne Koong
2026-01-27 23:37 ` Darrick J. Wong
2026-01-27 0:59 ` [PATCHSET v6 4/8] fuse: allow servers to use iomap for better file IO performance Joanne Koong
2026-01-27 2:22 ` Darrick J. Wong
2026-01-27 19:47 ` Joanne Koong
2026-01-27 23:21 ` Darrick J. Wong
2026-01-28 0:10 ` Joanne Koong
2026-01-28 0:34 ` Darrick J. Wong
2026-01-29 1:12 ` Joanne Koong
2026-01-29 20:02 ` Darrick J. Wong
2026-01-29 22:41 ` Darrick J. Wong
2026-01-29 22:50 ` Joanne Koong
2026-01-29 23:12 ` Darrick J. Wong
[not found] ` <176169810980.1424854.10557015500766654898.stgit@frogsfrogsfrogs>
2026-02-05 18:57 ` [PATCH 29/31] fuse: disable direct reclaim for any fuse server that uses iomap Chris Mason
2026-02-06 4:25 ` Darrick J. Wong
[not found] ` <176169810874.1424854.5037707950055785011.stgit@frogsfrogsfrogs>
2026-02-05 19:01 ` [PATCH 24/31] fuse: implement inline data file IO via iomap Chris Mason
2026-02-06 2:27 ` Darrick J. Wong
[not found] ` <176169810765.1424854.10969346031644824992.stgit@frogsfrogsfrogs>
2026-02-05 19:07 ` [PATCH 19/31] fuse: query filesystem geometry when using iomap Chris Mason
2026-02-06 2:17 ` Darrick J. Wong
[not found] ` <176169810656.1424854.15239592653019383193.stgit@frogsfrogsfrogs>
2026-02-05 19:12 ` [PATCH 14/31] fuse: implement buffered IO with iomap Chris Mason
2026-02-06 2:14 ` Darrick J. Wong
[not found] ` <176169810634.1424854.13084435884326863405.stgit@frogsfrogsfrogs>
2026-02-05 19:16 ` [PATCH 13/31] fuse_trace: implement direct " Chris Mason
2026-02-06 2:12 ` Darrick J. Wong
[not found] ` <176169810612.1424854.16053093294573829123.stgit@frogsfrogsfrogs>
2026-01-23 18:56 ` [PATCH 12/31] fuse: " Joanne Koong
2026-01-26 23:46 ` Darrick J. Wong
2026-02-05 19:19 ` Chris Mason
2026-02-06 2:08 ` Darrick J. Wong
2026-02-06 2:52 ` Chris Mason
2026-02-06 5:08 ` Darrick J. Wong
2026-02-06 14:27 ` Chris Mason
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260122223119.GB5900@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=bernd@bsbernd.com \
--cc=joannelkoong@gmail.com \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=miklos@szeredi.hu \
--cc=neal@gompa.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox