Skip to content

Commit dabb903

Browse files
szmiMiklos Szeredi
authored andcommitted
fuse: increase readdir buffer size
Increase the buffer size to the count requested by userspace. This improves performance. Signed-off-by: Miklos Szeredi <[email protected]> Signed-off-by: Bernd Schubert <[email protected]>
1 parent 467e245 commit dabb903

File tree

1 file changed

+14
-19
lines changed

1 file changed

+14
-19
lines changed

fs/fuse/readdir.c

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -335,35 +335,32 @@ static int fuse_readdir_uncached(struct file *file, struct dir_context *ctx)
335335
{
336336
int plus;
337337
ssize_t res;
338-
struct folio *folio;
339338
struct inode *inode = file_inode(file);
340339
struct fuse_mount *fm = get_fuse_mount(inode);
340+
struct fuse_conn *fc = fm->fc;
341341
struct fuse_io_args ia = {};
342-
struct fuse_args_pages *ap = &ia.ap;
343-
struct fuse_folio_desc desc = { .length = PAGE_SIZE };
342+
struct fuse_args *args = &ia.ap.args;
343+
void *buf;
344+
size_t bufsize = clamp((unsigned int) ctx->count, PAGE_SIZE, fc->max_pages << PAGE_SHIFT);
344345
u64 attr_version = 0, evict_ctr = 0;
345346
bool locked;
346347

347-
folio = folio_alloc(GFP_KERNEL, 0);
348-
if (!folio)
348+
buf = kvmalloc(bufsize, GFP_KERNEL);
349+
if (!buf)
349350
return -ENOMEM;
350351

352+
args->out_args[0].value = buf;
353+
351354
plus = fuse_use_readdirplus(inode, ctx);
352-
ap->args.out_pages = true;
353-
ap->num_folios = 1;
354-
ap->folios = &folio;
355-
ap->descs = &desc;
356355
if (plus) {
357356
attr_version = fuse_get_attr_version(fm->fc);
358357
evict_ctr = fuse_get_evict_ctr(fm->fc);
359-
fuse_read_args_fill(&ia, file, ctx->pos, PAGE_SIZE,
360-
FUSE_READDIRPLUS);
358+
fuse_read_args_fill(&ia, file, ctx->pos, bufsize, FUSE_READDIRPLUS);
361359
} else {
362-
fuse_read_args_fill(&ia, file, ctx->pos, PAGE_SIZE,
363-
FUSE_READDIR);
360+
fuse_read_args_fill(&ia, file, ctx->pos, bufsize, FUSE_READDIR);
364361
}
365362
locked = fuse_lock_inode(inode);
366-
res = fuse_simple_request(fm, &ap->args);
363+
res = fuse_simple_request(fm, args);
367364
fuse_unlock_inode(inode, locked);
368365
if (res >= 0) {
369366
if (!res) {
@@ -372,16 +369,14 @@ static int fuse_readdir_uncached(struct file *file, struct dir_context *ctx)
372369
if (ff->open_flags & FOPEN_CACHE_DIR)
373370
fuse_readdir_cache_end(file, ctx->pos);
374371
} else if (plus) {
375-
res = parse_dirplusfile(folio_address(folio), res,
376-
file, ctx, attr_version,
372+
res = parse_dirplusfile(buf, res, file, ctx, attr_version,
377373
evict_ctr);
378374
} else {
379-
res = parse_dirfile(folio_address(folio), res, file,
380-
ctx);
375+
res = parse_dirfile(buf, res, file, ctx);
381376
}
382377
}
383378

384-
folio_put(folio);
379+
kvfree(buf);
385380
fuse_invalidate_atime(inode);
386381
return res;
387382
}

0 commit comments

Comments
 (0)