Index: linux-5.9.1/fs/fuse/readdir.c =================================================================== --- linux-5.9.1.orig/fs/fuse/readdir.c 2020-11-04 00:44:46.705715697 +0100 +++ linux-5.9.1/fs/fuse/readdir.c 2020-11-04 00:44:46.701715653 +0100 @@ -318,30 +318,27 @@ { int plus; ssize_t res; - struct page *page; + size_t bufsize = 32768; + void *buf; struct inode *inode = file_inode(file); struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_io_args ia = {}; struct fuse_args_pages *ap = &ia.ap; - struct fuse_page_desc desc = { .length = PAGE_SIZE }; u64 attr_version = 0; bool locked; - page = alloc_page(GFP_KERNEL); - if (!page) + buf = vmalloc(bufsize); + if (!buf) return -ENOMEM; plus = fuse_use_readdirplus(inode, ctx); - ap->args.out_pages = true; - ap->num_pages = 1; - ap->pages = &page; - ap->descs = &desc; + ap->args.out_args[0].value = buf; if (plus) { attr_version = fuse_get_attr_version(fc); - fuse_read_args_fill(&ia, file, ctx->pos, PAGE_SIZE, + fuse_read_args_fill(&ia, file, ctx->pos, bufsize, FUSE_READDIRPLUS); } else { - fuse_read_args_fill(&ia, file, ctx->pos, PAGE_SIZE, + fuse_read_args_fill(&ia, file, ctx->pos, bufsize, FUSE_READDIR); } locked = fuse_lock_inode(inode); @@ -354,15 +351,14 @@ if (ff->open_flags & FOPEN_CACHE_DIR) fuse_readdir_cache_end(file, ctx->pos); } else if (plus) { - res = parse_dirplusfile(page_address(page), res, + res = parse_dirplusfile(buf, res, file, ctx, attr_version); } else { - res = parse_dirfile(page_address(page), res, file, - ctx); + res = parse_dirfile(buf, res, file, ctx); } } - __free_page(page); + vfree(buf); fuse_invalidate_atime(inode); return res; }