On 4/26/25 02:08, Joanne Koong wrote: > Add support for folios larger than one page size for readahead. > > Signed-off-by: Joanne Koong <joannelkoong@xxxxxxxxx> > Reviewed-by: Jeff Layton <jlayton@xxxxxxxxxx> > --- > fs/fuse/file.c | 36 +++++++++++++++++++++++++++--------- > 1 file changed, 27 insertions(+), 9 deletions(-) > > diff --git a/fs/fuse/file.c b/fs/fuse/file.c > index 1d38486fae50..9a31f2a516b9 100644 > --- a/fs/fuse/file.c > +++ b/fs/fuse/file.c > @@ -876,14 +876,13 @@ static void fuse_readpages_end(struct fuse_mount *fm, struct fuse_args *args, > fuse_io_free(ia); > } > > -static void fuse_send_readpages(struct fuse_io_args *ia, struct file *file) > +static void fuse_send_readpages(struct fuse_io_args *ia, struct file *file, > + unsigned int count) > { > struct fuse_file *ff = file->private_data; > struct fuse_mount *fm = ff->fm; > struct fuse_args_pages *ap = &ia->ap; > loff_t pos = folio_pos(ap->folios[0]); > - /* Currently, all folios in FUSE are one page */ > - size_t count = ap->num_folios << PAGE_SHIFT; > ssize_t res; > int err; > > @@ -918,6 +917,7 @@ static void fuse_readahead(struct readahead_control *rac) > struct inode *inode = rac->mapping->host; > struct fuse_conn *fc = get_fuse_conn(inode); > unsigned int max_pages, nr_pages; > + struct folio *folio = NULL; > > if (fuse_is_bad(inode)) > return; > @@ -939,8 +939,8 @@ static void fuse_readahead(struct readahead_control *rac) > while (nr_pages) { > struct fuse_io_args *ia; > struct fuse_args_pages *ap; > - struct folio *folio; > unsigned cur_pages = min(max_pages, nr_pages); > + unsigned int pages = 0; > > if (fc->num_background >= fc->congestion_threshold && > rac->ra->async_size >= readahead_count(rac)) > @@ -952,10 +952,12 @@ static void fuse_readahead(struct readahead_control *rac) > > ia = fuse_io_alloc(NULL, cur_pages); > if (!ia) > - return; > + break; > ap = &ia->ap; > > - while (ap->num_folios < cur_pages) { > + while (pages < cur_pages) { > + unsigned int folio_pages; > + > /* > * This returns a folio with a ref held on it. > * The ref needs to be held until the request is > @@ -963,13 +965,29 @@ static void fuse_readahead(struct readahead_control *rac) > * fuse_try_move_page()) drops the ref after it's > * replaced in the page cache. > */ > - folio = __readahead_folio(rac); > + if (!folio) > + folio = __readahead_folio(rac); > + > + folio_pages = folio_nr_pages(folio); > + if (folio_pages > cur_pages - pages) > + break; > + Hmm, so let's assume this would be a 2MB folio, but fc->max_pages is limited to 1MB - we not do read-ahead anymore? Thanks, Bernd > ap->folios[ap->num_folios] = folio; > ap->descs[ap->num_folios].length = folio_size(folio); > ap->num_folios++; > + pages += folio_pages; > + folio = NULL; > + } > + if (!pages) { > + fuse_io_free(ia); > + break; > } > - fuse_send_readpages(ia, rac->file); > - nr_pages -= cur_pages; > + fuse_send_readpages(ia, rac->file, pages << PAGE_SHIFT); > + nr_pages -= pages; > + } > + if (folio) { > + folio_end_read(folio, false); > + folio_put(folio); > } > } >