Skip to content

Commit 3568a95

Browse files
joannekoongMiklos Szeredi
authored andcommitted
fuse: support large folios for retrieves
Add support for folios larger than one page size for retrieves. Signed-off-by: Joanne Koong <[email protected]> Reviewed-by: Josef Bacik <[email protected]> Reviewed-by: Jeff Layton <[email protected]> Reviewed-by: Bernd Schubert <[email protected]> Signed-off-by: Miklos Szeredi <[email protected]>
1 parent 394244b commit 3568a95

File tree

1 file changed

+15
-10
lines changed

1 file changed

+15
-10
lines changed

fs/fuse/dev.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1849,7 +1849,7 @@ static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode,
18491849
unsigned int num;
18501850
unsigned int offset;
18511851
size_t total_len = 0;
1852-
unsigned int num_pages, cur_pages = 0;
1852+
unsigned int num_pages;
18531853
struct fuse_conn *fc = fm->fc;
18541854
struct fuse_retrieve_args *ra;
18551855
size_t args_size = sizeof(*ra);
@@ -1867,6 +1867,7 @@ static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode,
18671867

18681868
num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
18691869
num_pages = min(num_pages, fc->max_pages);
1870+
num = min(num, num_pages << PAGE_SHIFT);
18701871

18711872
args_size += num_pages * (sizeof(ap->folios[0]) + sizeof(ap->descs[0]));
18721873

@@ -1887,25 +1888,29 @@ static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode,
18871888

18881889
index = outarg->offset >> PAGE_SHIFT;
18891890

1890-
while (num && cur_pages < num_pages) {
1891+
while (num) {
18911892
struct folio *folio;
1892-
unsigned int this_num;
1893+
unsigned int folio_offset;
1894+
unsigned int nr_bytes;
1895+
unsigned int nr_pages;
18931896

18941897
folio = filemap_get_folio(mapping, index);
18951898
if (IS_ERR(folio))
18961899
break;
18971900

1898-
this_num = min_t(unsigned, num, PAGE_SIZE - offset);
1901+
folio_offset = ((index - folio->index) << PAGE_SHIFT) + offset;
1902+
nr_bytes = min(folio_size(folio) - folio_offset, num);
1903+
nr_pages = (offset + nr_bytes + PAGE_SIZE - 1) >> PAGE_SHIFT;
1904+
18991905
ap->folios[ap->num_folios] = folio;
1900-
ap->descs[ap->num_folios].offset = offset;
1901-
ap->descs[ap->num_folios].length = this_num;
1906+
ap->descs[ap->num_folios].offset = folio_offset;
1907+
ap->descs[ap->num_folios].length = nr_bytes;
19021908
ap->num_folios++;
1903-
cur_pages++;
19041909

19051910
offset = 0;
1906-
num -= this_num;
1907-
total_len += this_num;
1908-
index++;
1911+
num -= nr_bytes;
1912+
total_len += nr_bytes;
1913+
index += nr_pages;
19091914
}
19101915
ra->inarg.offset = outarg->offset;
19111916
ra->inarg.size = total_len;

0 commit comments

Comments
 (0)