What Happens When a Provider Advertises the Buffered‑Write Surface in the FUSE Driver

When a VFS provider implements the buffered‑write API methods—including openWriteBufferSync, releaseWriteBufferSync, and optionally openWriteBufferForCreateSync—the FUSE driver in cloudflare/computer switches from pure‑direct‑write mode to a hybrid buffered mode that accumulates writes in memory and flushes them only on fsync, flush, or release.

The FUSE driver in the cloudflare/computer repository dynamically adapts its write strategy based on provider capabilities. When a provider advertises the buffered‑write surface in the FUSE driver, the system enables an in‑memory buffering layer that batches small writes and defers persistence until explicit synchronization points, eliminating per‑write system‑call overhead and enabling atomic write semantics.

Detection of the Buffered‑Write Surface

Early in packages/computerd/src/fuse/driver.ts, the driver inspects the supplied vfs object to determine which write surface the provider supports. The detection logic first verifies direct‑write primitives, then checks for buffered‑write extensions:

const hasDirectWrites =
  directWriteVfs.createFileSync !== undefined &&
  directWriteVfs.writeRangeSync !== undefined &&
  directWriteVfs.truncateFileSync !== undefined;

const hasBufferedWrites =
  hasDirectWrites &&
  directWriteVfs.openWriteBufferSync !== undefined &&
  directWriteVfs.releaseWriteBufferSync !== undefined;

const hasDeferredCreate =
  hasBufferedWrites && directWriteVfs.openWriteBufferForCreateSync !== undefined;

If hasBufferedWrites evaluates to true, the driver initializes the hybrid buffered mode. This mode creates an in‑memory Buffer for each FileEntry and tracks dirty ranges rather than forwarding every write immediately to the underlying VFS.

In‑Memory Buffering Architecture

For every opened file, the driver instantiates a FileEntry structure that holds an in‑memory buffer (entry.buf). Write operations apply changes exclusively to this buffer, and the entry is marked dirty with a list of modified ranges (entry.dirtyRanges).

This design provides two immediate benefits:

  • Eliminated round‑trips: Small, frequent writes complete entirely in memory without system calls to the provider.
  • Dirty‑range tracking: The driver maintains precise metadata about which byte ranges have changed, enabling efficient ranged writes during flush.

No data touches the underlying VFS during the write syscall itself. The provider remains unaware of the file changes until the driver explicitly flushes the buffer.

Deferred File Creation Semantics

When the provider also implements openWriteBufferForCreateSync, the driver supports deferred file creation. In this pattern, the driver calls the provider’s createFileSync early to establish the inode and metadata, but keeps the file content empty in the VFS backend.

This approach satisfies "create‑on‑open" semantics while deferring the bulk data transfer. The file exists in the namespace immediately, yet the provider stores no data until the buffered content flushes. This is particularly useful for providers that charge per byte stored or require atomic file appearance.

Flush and Persistence Mechanism

The driver persists buffered data through the flushEntry(path) function, invoked during flush, release, or explicit fsync operations. According to the implementation in packages/computerd/src/fuse/driver.ts (lines 66‑86), this function:

  1. Extracts the dirty slice from the in‑memory buffer using the accumulated dirtyRanges.
  2. Decides between ranged writes (writeFileRangesSync) or a full write (writeFileSync) based on the provider’s preferences and the distribution of dirty ranges.
  3. Passes the original mode bits to preserve file permissions.
  4. Clears dirty flags and releases the buffer reference.

If the provider prefers ranged writes, the driver supplies the specific dirty ranges, allowing the VFS backend to apply only the changed portions rather than rewriting the entire file.

Error Handling and Limits

All buffer‑related operations return POSIX‑style error numbers. The driver translates JavaScript exceptions into errno values using toErrno(error) before surfacing them to the kernel. For example, if a write would cause the file to exceed MAX_FILE_BYTES, the driver returns ERRNO.EFBIG.

This error translation ensures that applications interacting with the FUSE mount receive standard Linux error codes (like EFBIG, ENOMEM, or EIO) rather than Java stack traces or internal exceptions.

Code Example: Implementing the Buffered‑Write Surface

To advertise the buffered‑write surface, a provider must implement the extended interface:

import { DirectWriteVfs } from '@cloudflare/computer';

interface BufferedWriteVfs extends DirectWriteVfs {
  openWriteBufferSync(path: string): void;
  releaseWriteBufferSync(path: string): void;
  // Optional: enables deferred creation
  openWriteBufferForCreateSync(
    path: string, 
    options: { mode: number }
  ): void;
}

const vfs: BufferedWriteVfs = {
  createFileSync(path, mode) { /* ... */ },
  writeRangeSync(path, offset, data) { /* ... */ },
  truncateFileSync(path, size) { /* ... */ },
  openWriteBufferSync(path) { /* allocate temp resources */ },
  releaseWriteBufferSync(path) { /* cleanup */ },
  openWriteBufferForCreateSync(path, { mode }) { /* create empty inode */ }
};

// Mount with FUSE driver
const fuse = new FuseDriver(vfs);
fuse.mount('/mnt/computer');

When application code writes to /mnt/computer, the driver buffers the data internally:

import { writeFileSync, sync } from 'fs';

// Buffered in memory; no VFS call yet
writeFileSync('/mnt/computer/buffered.bin', Buffer.from('buffered-write'));

// Forces flushEntry() and persists to provider
sync('/mnt/computer/buffered.bin');

Summary

When a provider advertises the buffered‑write surface in the FUSE driver, the system behavior changes significantly:

  • Capability detection in packages/computerd/src/fuse/driver.ts checks for openWriteBufferSync and releaseWriteBufferSync to enable hybrid mode.
  • In‑memory buffering accumulates writes in a FileEntry buffer, tracking dirty ranges without immediate VFS round‑trips.
  • Deferred creation allows early inode allocation via openWriteBufferForCreateSync while postponing data transfer.
  • Atomic flushing via flushEntry writes dirty ranges using either writeFileRangesSync or writeFileSync, clearing buffers only after successful persistence.
  • POSIX error translation ensures standard errno values (like EFBIG for files exceeding MAX_FILE_BYTES) reach the application layer.

Frequently Asked Questions

How does the FUSE driver detect buffered‑write support?

The driver inspects the provider object at initialization in packages/computerd/src/fuse/driver.ts. It verifies that openWriteBufferSync and releaseWriteBufferSync are defined as functions on the VFS object. If these methods exist alongside the base direct‑write primitives, the driver sets hasBufferedWrites to true and initializes the buffering layer.

What is the difference between direct writes and buffered writes in this driver?

Direct writes invoke writeRangeSync or truncateFileSync immediately for every operation, causing a system‑call round‑trip per write. Buffered writes store data in a FileEntry memory buffer and apply changes only during flush or release, batching multiple small writes into a single VFS operation and reducing overhead.

When does the driver actually write data to the underlying VFS?

The driver persists buffered data when it calls flushEntry(path), which occurs during explicit fsync operations, implicit flush requests from the kernel, or final release when the file descriptor closes. Until one of these events fires, the data remains exclusively in the driver’s memory buffer.

What happens if a buffered write exceeds MAX_FILE_BYTES?

The driver returns ERRNO.EFBIG (file too large) during the write operation. This error propagates through the toErrno(error) translation layer and surfaces to the application as a standard POSIX EFBIG error code, preventing the buffer from growing beyond the configured MAX_FILE_BYTES limit.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →