mirror of https://github.com/torvalds/linux.git
fuse: increase readdir buffer size
Increase the buffer size to the count requested by userspace. This improves performance. Signed-off-by: Miklos Szeredi <miklos@szeredi.hu> Signed-off-by: Bernd Schubert <bschubert@ddn.com>
This commit is contained in:
parent
467e245d47
commit
dabb903910
|
|
@ -335,35 +335,32 @@ static int fuse_readdir_uncached(struct file *file, struct dir_context *ctx)
|
||||||
{
|
{
|
||||||
int plus;
|
int plus;
|
||||||
ssize_t res;
|
ssize_t res;
|
||||||
struct folio *folio;
|
|
||||||
struct inode *inode = file_inode(file);
|
struct inode *inode = file_inode(file);
|
||||||
struct fuse_mount *fm = get_fuse_mount(inode);
|
struct fuse_mount *fm = get_fuse_mount(inode);
|
||||||
|
struct fuse_conn *fc = fm->fc;
|
||||||
struct fuse_io_args ia = {};
|
struct fuse_io_args ia = {};
|
||||||
struct fuse_args_pages *ap = &ia.ap;
|
struct fuse_args *args = &ia.ap.args;
|
||||||
struct fuse_folio_desc desc = { .length = PAGE_SIZE };
|
void *buf;
|
||||||
|
size_t bufsize = clamp((unsigned int) ctx->count, PAGE_SIZE, fc->max_pages << PAGE_SHIFT);
|
||||||
u64 attr_version = 0, evict_ctr = 0;
|
u64 attr_version = 0, evict_ctr = 0;
|
||||||
bool locked;
|
bool locked;
|
||||||
|
|
||||||
folio = folio_alloc(GFP_KERNEL, 0);
|
buf = kvmalloc(bufsize, GFP_KERNEL);
|
||||||
if (!folio)
|
if (!buf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
args->out_args[0].value = buf;
|
||||||
|
|
||||||
plus = fuse_use_readdirplus(inode, ctx);
|
plus = fuse_use_readdirplus(inode, ctx);
|
||||||
ap->args.out_pages = true;
|
|
||||||
ap->num_folios = 1;
|
|
||||||
ap->folios = &folio;
|
|
||||||
ap->descs = &desc;
|
|
||||||
if (plus) {
|
if (plus) {
|
||||||
attr_version = fuse_get_attr_version(fm->fc);
|
attr_version = fuse_get_attr_version(fm->fc);
|
||||||
evict_ctr = fuse_get_evict_ctr(fm->fc);
|
evict_ctr = fuse_get_evict_ctr(fm->fc);
|
||||||
fuse_read_args_fill(&ia, file, ctx->pos, PAGE_SIZE,
|
fuse_read_args_fill(&ia, file, ctx->pos, bufsize, FUSE_READDIRPLUS);
|
||||||
FUSE_READDIRPLUS);
|
|
||||||
} else {
|
} else {
|
||||||
fuse_read_args_fill(&ia, file, ctx->pos, PAGE_SIZE,
|
fuse_read_args_fill(&ia, file, ctx->pos, bufsize, FUSE_READDIR);
|
||||||
FUSE_READDIR);
|
|
||||||
}
|
}
|
||||||
locked = fuse_lock_inode(inode);
|
locked = fuse_lock_inode(inode);
|
||||||
res = fuse_simple_request(fm, &ap->args);
|
res = fuse_simple_request(fm, args);
|
||||||
fuse_unlock_inode(inode, locked);
|
fuse_unlock_inode(inode, locked);
|
||||||
if (res >= 0) {
|
if (res >= 0) {
|
||||||
if (!res) {
|
if (!res) {
|
||||||
|
|
@ -372,16 +369,14 @@ static int fuse_readdir_uncached(struct file *file, struct dir_context *ctx)
|
||||||
if (ff->open_flags & FOPEN_CACHE_DIR)
|
if (ff->open_flags & FOPEN_CACHE_DIR)
|
||||||
fuse_readdir_cache_end(file, ctx->pos);
|
fuse_readdir_cache_end(file, ctx->pos);
|
||||||
} else if (plus) {
|
} else if (plus) {
|
||||||
res = parse_dirplusfile(folio_address(folio), res,
|
res = parse_dirplusfile(buf, res, file, ctx, attr_version,
|
||||||
file, ctx, attr_version,
|
|
||||||
evict_ctr);
|
evict_ctr);
|
||||||
} else {
|
} else {
|
||||||
res = parse_dirfile(folio_address(folio), res, file,
|
res = parse_dirfile(buf, res, file, ctx);
|
||||||
ctx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
folio_put(folio);
|
kvfree(buf);
|
||||||
fuse_invalidate_atime(inode);
|
fuse_invalidate_atime(inode);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue