Skip to content

How to handle READ requests for files opened in passthrough mode? #677

Description

@oxalica

As in our example for passthrough, READ operation is not implemented since kernel should handle all of them directly on the backing file instead. But turns out kernel can still send READ requests to us after we reply OPEN request by opened_passthrough in some cases, namely on readahead(2).

Here is the C code to trigger that.

#define _GNU_SOURCE
#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main() {
    int f = open("/path/to/fuse/mnt/passthrough", O_RDONLY | O_CLOEXEC);
    assert(f >= 0);
    readahead(f, 0, 4096);
}

Running the passthrough example FUSE with:
cargo build --example passthrough && sudo RUST_LOG=debug ./target/debug/examples/passthrough /path/to/fuse/mnt

Then compile and run the C code above. We'll get some logs from the FUSE daemon:

[2026-05-03T18:25:11Z DEBUG fuser::request] FUSE( 30) ino 0x0000000000000001 LOOKUP name "passthrough" thread=fuser-0
[2026-05-03T18:25:11Z DEBUG fuser::request] FUSE( 32) ino 0x0000000000000002 OPEN flags 0x8000 thread=fuser-0
MISS! new BackingId { channel: (Weak), backing_id: 4 }
  -> opened_passthrough(4, 0, BackingId { channel: (Weak), backing_id: 4 });

[2026-05-03T18:25:11Z DEBUG fuser::request] FUSE( 34) ino 0x0000000000000002 READ fh FileHandle(4), offset Ok(0), size 4096 thread=fuser-0
[2026-05-03T18:25:11Z WARN  fuser] [Not Implemented] read(ino: INodeNo(
        0x2,
    ), fh: 4, offset: 0, size: 4096, flags: OpenFlags(
        0x8000,
    ), lock_owner: None)
[2026-05-03T18:25:11Z DEBUG fuser::request] FUSE( 36) ino 0x0000000000000002 RELEASE fh FileHandle(4), flags 0x8000, flush false, lock owner None thread=fuser-0
Put fh 4
Put fh 4, was BackingId { channel: (Weak), backing_id: 4 }

If we want to correctly handle this, there should still be a fallback path for READ requests, and file descriptors are required to be kept open. This makes code much more complicated and results in readahead slowing down the performance, which seems wrong to me...
Or probably it is the kernel to be blamed in this case?

EDIT: My kernel version is 6.18.24

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions