Skip to content

Linux: 9pfuse drops directory entries when userspace buffer is small #720

@Arusekk

Description

@Arusekk

Apparently 9pfuse drops directory entries, just as the comment for src/cmd/9pfuse/main.c:/^fusereaddir says:

/* [...]
 * We assume 9P directory read semantics: a read at offset 0 rewinds
 * and a read at any other offset starts where we left off.
 * If it became necessary, we could implement a crude seek
 * or cache the entire list of directory entries.
 * [...]
 */

So I guess it has just become necessary (at least to seek into the middle of last returned array).

Another option is to set FOPEN_CACHE_DIR on out.open_flags if it is set in in.flags in src/cmd/9pfuse/main.c:/^_fuseopen.
This would solve issues with Linux 4.20+ (this flag is also acknowledged by latest macfuse and DragonflyBSD, but they do not implement any logic if I understand correctly).

This can be reproduced on Alpine Linux, for example by mounting an ISO from 9legacy or 9front, and running ls amd64/bin (or listing something else that contains enough files).

Since musl uses getdents64 buffer of 2048, and Linux forwards it as PAGE_SIZE, it sometimes cannot fit all entries into the buffer (despite fuse_dirent being less packed — min. 32/entry — than linux_dirent64 — min. 24/entry, 8B less for most name lengths).
86 files in a directory are enough to trigger this lossy readdir, and it will never happen with under 43 files, assuming the classic 9P limit of filenames ≤28B.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions