Stream: jco

Topic: How to implement mutate-ditectory in jco


view this post on Zulip Mendy Berger (Mar 26 2026 at 11:43):

I'm trying to implement wasi:fs mutate-ditectory in jco and am confused by how wasmtime deals with it.

I'm trying to understand how descriptor-flags — and the mutate-directory flag in particular — is supposed to behave. A couple of things we've noticed with wasmtime:

  1. It doesn't appear to actually check mutate-directory.
  2. It passes down directory permissions from the parent, even if the guest didn't explicitly request them.

We're trying to determine whether this is a deviation from the spec, and if so, whether jco should align with wasmtime's behavior or follow the spec strictly.

Thoughts anyone?

view this post on Zulip Victor Adossi (Mar 26 2026 at 12:04):

To expand on the context above (before we move this discussion):

This is in relation to this PR (if you want to eyeball some code!):
https://github.com/bytecodealliance/jco/pull/1303

If I were to attempt to summarize where we're at now in the interest of saving time:

  1. Jco's preview2-shim library never handled mutate-directory properly (or at all!)
  2. Jco has a test suite that is borrowed from upstream wasmtime w/ p1 components in it
  3. Fixing preview2-shim to properly handle mutate-directory causes failures in the p1 components upstream
  4. IIRC those components are coming through adapted (am I wrong about this? build.rs looks to be composing p1_ prefixed components), but we're not seeing mutate-directory set on them properly, when the root has been set with mutate-directory (see the PR above, every new preopen gets it by default in that PR).
  5. We're seeing "RO filesystem" errors ostensibly caused by (4)

P1 did not have mutate directory AFAIK so I think this was a P1 -> P2 thing specifically (if anyone can still remember back that far!)

When I look at upstream wasmtime, I see that P1 ctx is doing a little bit of munging to get p1's write open mode to also translate to mutate directory. That code seems to me like where p1 components are getting the ability to run properly in host designed for/properly adhering to P2.

That said, looking through I can't find the exact codepath that makes this work -- is my understanding correct here?

Does the preopened dir automatically get WRITE, then that WRITE is eventually turned back into mutate directory when the flags are checked?

Trying to figure out what exactly wasmtime is doing to smooth this over, and why the logic in Jco is falling afoul of adapted P1 components in that PR.
if we're understanding the adjustment wasmtime is making correctly, and we're going for backwards compat/not breaking existing users, then the fix seems to be to augment Jco's openAt (on that branch) to interpret WRITE permissions on directories that are opened as MUTATE_DIRECTORYs so that it can be propagated down.

Would love some feedback here @Yosh Wuyts @Pat Hickey and anyone that might have context from back then!

view this post on Zulip Yosh Wuyts (Mar 30 2026 at 07:58):

reading through this, I don't actually recall much about this. Sorry I can't add much historical context here

view this post on Zulip Victor Adossi (Mar 30 2026 at 13:52):

No worries, thanks for chiming in -- yeah it's quite a while ago and the code is almost self-explanatory. We must be missing something obvious here.

view this post on Zulip Mendy Berger (Mar 31 2026 at 17:59):

I also filed an issue against wasmtime for this https://github.com/bytecodealliance/wasmtime/issues/12912

view this post on Zulip Alex Crichton (Mar 31 2026 at 18:47):

I alas also don't really have much more context to add here. My best guess is that there were ambitions to make a better permissions/hierarchy than POSIX and it may never have come to fruition, and it might be time to scale things back


Last updated: Apr 13 2026 at 00:25 UTC