Skip to content

Commit 3eab9d7

Browse files
josefbacikMiklos Szeredi
authored andcommitted
fuse: convert readahead to use folios
Currently we're using the __readahead_batch() helper which populates our fuse_args_pages->pages array with pages. Convert this to use the newer folio based pattern which is to call readahead_folio() to get the next folio in the read ahead batch. I've updated the code to use things like folio_size() and to take into account larger folio sizes, but this is purely to make that eventual work easier to do, we currently will not get large folios so this is more future proofing than actual support. [SzM: remove check for readahead_folio() won't return NULL (at least for now) so remove ugly assign in conditional.] Signed-off-by: Josef Bacik <[email protected]> Signed-off-by: Miklos Szeredi <[email protected]>
1 parent aaa3242 commit 3eab9d7

File tree

1 file changed

+23
-13
lines changed

1 file changed

+23
-13
lines changed

fs/fuse/file.c

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,6 @@ static void fuse_readpages_end(struct fuse_mount *fm, struct fuse_args *args,
945945
struct folio *folio = page_folio(ap->pages[i]);
946946

947947
folio_end_read(folio, !err);
948-
folio_put(folio);
949948
}
950949
if (ia->ff)
951950
fuse_file_put(ia->ff, false);
@@ -994,7 +993,7 @@ static void fuse_readahead(struct readahead_control *rac)
994993
struct inode *inode = rac->mapping->host;
995994
struct fuse_inode *fi = get_fuse_inode(inode);
996995
struct fuse_conn *fc = get_fuse_conn(inode);
997-
unsigned int i, max_pages, nr_pages = 0;
996+
unsigned int max_pages, nr_pages;
998997
pgoff_t first = readahead_index(rac);
999998
pgoff_t last = first + readahead_count(rac) - 1;
1000999

@@ -1006,9 +1005,22 @@ static void fuse_readahead(struct readahead_control *rac)
10061005
max_pages = min_t(unsigned int, fc->max_pages,
10071006
fc->max_read / PAGE_SIZE);
10081007

1009-
for (;;) {
1008+
/*
1009+
* This is only accurate the first time through, since readahead_folio()
1010+
* doesn't update readahead_count() from the previous folio until the
1011+
* next call. Grab nr_pages here so we know how many pages we're going
1012+
* to have to process. This means that we will exit here with
1013+
* readahead_count() == folio_nr_pages(last_folio), but we will have
1014+
* consumed all of the folios, and read_pages() will call
1015+
* readahead_folio() again which will clean up the rac.
1016+
*/
1017+
nr_pages = readahead_count(rac);
1018+
1019+
while (nr_pages) {
10101020
struct fuse_io_args *ia;
10111021
struct fuse_args_pages *ap;
1022+
struct folio *folio;
1023+
unsigned cur_pages = min(max_pages, nr_pages);
10121024

10131025
if (fc->num_background >= fc->congestion_threshold &&
10141026
rac->ra->async_size >= readahead_count(rac))
@@ -1018,21 +1030,19 @@ static void fuse_readahead(struct readahead_control *rac)
10181030
*/
10191031
break;
10201032

1021-
nr_pages = readahead_count(rac) - nr_pages;
1022-
if (nr_pages > max_pages)
1023-
nr_pages = max_pages;
1024-
if (nr_pages == 0)
1025-
break;
1026-
ia = fuse_io_alloc(NULL, nr_pages);
1033+
ia = fuse_io_alloc(NULL, cur_pages);
10271034
if (!ia)
10281035
return;
10291036
ap = &ia->ap;
1030-
nr_pages = __readahead_batch(rac, ap->pages, nr_pages);
1031-
for (i = 0; i < nr_pages; i++) {
1032-
ap->descs[i].length = PAGE_SIZE;
1037+
1038+
while (ap->num_pages < cur_pages) {
1039+
folio = readahead_folio(rac);
1040+
ap->pages[ap->num_pages] = &folio->page;
1041+
ap->descs[ap->num_pages].length = folio_size(folio);
1042+
ap->num_pages++;
10331043
}
1034-
ap->num_pages = nr_pages;
10351044
fuse_send_readpages(ia, rac->file);
1045+
nr_pages -= cur_pages;
10361046
}
10371047
}
10381048

0 commit comments

Comments
 (0)