Skip to content

fuse: back uncached readdir buffers with pages#1427

Open
vfsci-bot[bot] wants to merge 1 commit into
vfs.base.cifrom
pw/1096931/vfs.base.ci
Open

fuse: back uncached readdir buffers with pages#1427
vfsci-bot[bot] wants to merge 1 commit into
vfs.base.cifrom
pw/1096931/vfs.base.ci

Conversation

@vfsci-bot
Copy link
Copy Markdown

@vfsci-bot vfsci-bot Bot commented May 19, 2026

Series: https://patchwork.kernel.org/project/linux-fsdevel/list/?series=1096931
Submitter: Matthew R. Ochs
Version: 3
Patches: 1/1
Message-ID: <20260519004746.3203156-1-mochs@nvidia.com>
Base: vfs.base.ci
Lore: https://lore.kernel.org/linux-fsdevel/20260519004746.3203156-1-mochs@nvidia.com


Automated by ml2pr

Commit dabb903 ("fuse: increase readdir buffer size") changed
fuse_readdir_uncached() to size its temporary buffer from ctx->count.
This is useful for overlayfs and other in-kernel callers that use
INT_MAX to indicate an unlimited directory read.

The buffer is capped by fc->max_pages converted to bytes with PAGE_SIZE.
However, fc->max_pages is a page-count limit, not a byte-sized payload
limit. READDIR is a read-side operation, so include fc->max_read in the
cap. Also keep fc->max_write in the cap: it is the daemon-advertised
byte-sized payload limit relevant to virtiofs in the failing
configuration, while fc->max_read can remain effectively unlimited there.

The larger buffer is also currently supplied as a kvec output argument.
For virtiofs, kvec arguments are copied through req->argbuf, which is
allocated with kmalloc(..., GFP_ATOMIC). A large readdir buffer can
therefore require a multi-megabyte contiguous atomic allocation and fail
with -ENOMEM.

This was observed with a 64K-page guest on a 4K-page host, using an
overlayfs mount whose lower directory is on virtiofs. Reading a merged
directory through overlayfs failed with:

  ls: reading directory '<path>': Cannot allocate memory

Avoid the oversized request and the large bounce-buffer allocation by
capping the requested byte size by fc->max_pages, fc->max_read, and
fc->max_write, then backing the uncached readdir output with pages and
setting out_pages. The virtiofs transport can then pass the pages as
scatter-gather entries instead of copying the output through argbuf.

Map the pages with vm_map_ram() only while parsing the returned dirents,
so the existing parser can continue to operate on a linear kernel mapping.

Fixes: dabb903 ("fuse: increase readdir buffer size")
Cc: stable@vger.kernel.org
Signed-off-by: Matthew R. Ochs <mochs@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant