On Fri, Jul 11, 2025 at 9:41 PM Darrick J. Wong <djwong@xxxxxxxxxx> wrote: > > On Wed, Jul 09, 2025 at 03:10:20PM -0700, Joanne Koong wrote: > > Use iomap for dirty folio writeback in ->writepages(). > > This allows for granular dirty writeback of large folios. > > > > Only the dirty portions of the large folio will be written instead of > > having to write out the entire folio. For example if there is a 1 MB > > large folio and only 2 bytes in it are dirty, only the page for those > > dirty bytes will be written out. > > > > .dirty_folio needs to be set to iomap_dirty_folio so that the bitmap > > iomap uses for dirty tracking correctly reflects dirty regions that need > > to be written back. > > > > Signed-off-by: Joanne Koong <joannelkoong@xxxxxxxxx> > > --- > > fs/fuse/file.c | 127 +++++++++++++++++++++++++++++-------------------- > > 1 file changed, 76 insertions(+), 51 deletions(-) > > > > diff --git a/fs/fuse/file.c b/fs/fuse/file.c > > index cadad61ef7df..70bbc8f26459 100644 > > --- a/fs/fuse/file.c > > +++ b/fs/fuse/file.c > > @@ -2100,7 +2101,7 @@ struct fuse_fill_wb_data { > > struct fuse_file *ff; > > struct inode *inode; > > unsigned int max_folios; > > - unsigned int nr_pages; > > + unsigned int nr_bytes; > > I don't know if fuse servers are ever realistically going to end up with > a large number of 1M folios, but at least in theory iomap is capable of > queuing ~4096 folios into a single writeback context. Does this need to > account for that? In fuse_writepage_need_send(), the writeback request gets sent out if max pages can be exceeded (eg if ((data->nr_bytes + len) / PAGE_SIZE > fc->max_pages)). max pages has a limit of 65535, which gives a limit in bytes of 256 MB (eg 65535 * PAGE_SIZE), so I think having unsigned int here for nr_bytes is okay. > > > }; > > > > static bool fuse_pages_realloc(struct fuse_fill_wb_data *data) > > @@ -2141,22 +2142,29 @@ static void fuse_writepages_send(struct fuse_fill_wb_data *data) > > spin_unlock(&fi->lock); > > } > > > > -static bool fuse_writepage_need_send(struct fuse_conn *fc, struct folio *folio, > > - struct fuse_args_pages *ap, > > +static bool fuse_writepage_need_send(struct fuse_conn *fc, loff_t pos, > > + unsigned len, struct fuse_args_pages *ap, > > struct fuse_fill_wb_data *data) > > { > > + struct folio *prev_folio; > > + struct fuse_folio_desc prev_desc; > > + loff_t prev_pos; > > + > > WARN_ON(!ap->num_folios); > > > > /* Reached max pages */ > > - if (data->nr_pages + folio_nr_pages(folio) > fc->max_pages) > > + if ((data->nr_bytes + len) / PAGE_SIZE > fc->max_pages) > > >> PAGE_SHIFT ? Nice, i'll change this to >> PAGE_SHIFT. Thanks for looking through the patchset. > > Otherwise this looks decent to me. > > --D > > > return true;