Skip to content

[WasmFS] Use readwrite-unsafe access handles in the OPFS backend - #27937

Open
JulesPatmanidis wants to merge 5 commits into
emscripten-core:mainfrom
JulesPatmanidis:wasmfs-opfs-readwrite-unsafe
Open

JulesPatmanidis wants to merge 5 commits into
emscripten-core:mainfrom
JulesPatmanidis:wasmfs-opfs-readwrite-unsafe

Conversation

@JulesPatmanidis

Copy link
Copy Markdown
Contributor

The OPFS backend used exclusive sync access handles for files opened for writing and Blobs for files opened read-only, so that several tabs could read the same file. Reads through a Blob are slow, especially from several threads (#27134), and a file open for writing blocks every other tab and worker.

This change opens all files with {mode: 'readwrite-unsafe'} when supported by the browser, which allows several handles on the same file. Read-only opens now also use an access handle in that case.

Browsers without support for mode (Firefox and Safari currently) accept the option silently and return an exclusive handle, so we can't tell if it is supported just from the result. Instead, the first open passes an options object with a getter for mode and checks whether the browser read it. If the browser reads mode but rejects the value with a TypeError, the backend treats it as unsupported.

If not supported, write opens use an exclusive handle and read-only opens use a Blob just as before.

This only affects builds with pthreads, since only those use sync access handles.

Behavior changes in browsers that support mode:

  • Several tabs or workers can open the same file for writing at the same time. Previously the second open returned EACCES.
  • open with O_RDONLY | O_TRUNC now truncates the file as on Linux and in the JS FS. Previously the truncation did not happen because the file was read through a Blob.

Also removes the createSyncAccessHandle.length check and its {mode: 'in-place'} branch. length is 0 in all current browsers because the options argument is optional, so that branch never ran.

Tests:

  • test_wasmfs_opfs expects the O_RDONLY | O_TRUNC truncation to succeed in pthreads builds running in Chrome 121 or newer, and to fail as before otherwise.
  • New test_wasmfs_opfs_shared checks that WasmFS can open a file in every mode while another context holds a readwrite-unsafe handle for it.

Open questions

  1. Unlink and rename while a file is open read-only.

Because read-only opens now hold an access handle, OPFS refuses to remove or move the file while it is open. In Chromium with this change, unlink or rename on a file that has an open read-only fd fails with EIO. Previously this only happened for files open for writing.

A related, smaller effect: a read-only open now holds a lock that blocks contexts needing an exclusive handle, for example, a truncate on a file with no open fd in another tab (which uses createWritable).

Is this a reasonable limitation that can just be documented (this happens anyway for files open for writing), or do you prefer a different approach?

  1. Should this get a ChangeLog entry? I can add something like: "The WasmFS OPFS backend now uses readwrite-unsafe sync access handles in pthreads builds if supported by the browser. Files can then be opened by several tabs or workers at the same time, and files opened read-only are read much faster from multiple threads."

Fixes #21869
Should help with #27134

@JulesPatmanidis

Copy link
Copy Markdown
Contributor Author

@tlively, since you opened #21869, could you take a look at the open questions? Thanks!

@kripken kripken added the wasmfs label Oct 9, 2026
@tlively

tlively commented Oct 9, 2026

Copy link
Copy Markdown
Member

Yes, I think this is worth doing. Let's just document the limitations and add a changelog entry so users are aware of the changes.

@JulesPatmanidis

Copy link
Copy Markdown
Contributor Author

Great!

I added a note to wasmfs_create_opfs_backend in wasmfs.h describing the tradeoff and added the changelog entry.

I will mark this ready for review when CI passes.

@JulesPatmanidis
JulesPatmanidis marked this pull request as ready for review October 10, 2026 08:44

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WasmFS: Use "readwrite-unsafe" in OPFS backend

3 participants