Use iomap for folio laundering, which will do granular dirty writeback when laundering a large folio. Signed-off-by: Joanne Koong <joannelkoong@xxxxxxxxx> --- fs/fuse/file.c | 49 +++++++++---------------------------------------- 1 file changed, 9 insertions(+), 40 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index db6804f6cc1d..800f478ad683 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -2060,45 +2060,6 @@ static struct fuse_writepage_args *fuse_writepage_args_setup(struct folio *folio return wpa; } -static int fuse_writepage_locked(struct folio *folio) -{ - struct address_space *mapping = folio->mapping; - struct inode *inode = mapping->host; - struct fuse_inode *fi = get_fuse_inode(inode); - struct fuse_writepage_args *wpa; - struct fuse_args_pages *ap; - struct fuse_file *ff; - int error = -EIO; - - ff = fuse_write_file_get(fi); - if (!ff) - goto err; - - wpa = fuse_writepage_args_setup(folio, ff); - error = -ENOMEM; - if (!wpa) - goto err_writepage_args; - - ap = &wpa->ia.ap; - ap->num_folios = 1; - - folio_start_writeback(folio); - fuse_writepage_args_page_fill(wpa, folio, 0); - - spin_lock(&fi->lock); - list_add_tail(&wpa->queue_entry, &fi->queued_writes); - fuse_flush_writepages(inode); - spin_unlock(&fi->lock); - - return 0; - -err_writepage_args: - fuse_file_put(ff, false); -err: - mapping_set_error(folio->mapping, error); - return error; -} - struct fuse_fill_wb_data { struct fuse_writepage_args *wpa; struct fuse_file *ff; @@ -2275,8 +2236,16 @@ static int fuse_writepages(struct address_space *mapping, static int fuse_launder_folio(struct folio *folio) { int err = 0; + struct fuse_fill_wb_data data = { + .inode = folio->mapping->host, + }; + struct iomap_writepage_ctx wpc = { + .iomap.type = IOMAP_MAPPED, + .private = &data, + }; + if (folio_clear_dirty_for_io(folio)) { - err = fuse_writepage_locked(folio); + err = iomap_writeback_dirty_folio(folio, NULL, &wpc, &fuse_writeback_ops); if (!err) folio_wait_writeback(folio); } -- 2.47.1