You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Populate FUSE stat block metadata so st_blocks consumers such as du see non-zero usage for files on the mount. The driver now preserves provider-supplied block fields and derives them for pending or buffered in-memory stats.
Add regression coverage for persisted, empty, pending-create, and dirty buffered files. Document the setup traps around fuse-native builds, clean-checkout test builds, and privileged real-FUSE tests.
Copy file name to clipboardExpand all lines: AGENTS.md
+54Lines changed: 54 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -28,6 +28,60 @@ the file directly when the trigger applies:
28
28
|[`capnweb`](.agents/skills/capnweb/SKILL.md)| Touching anything that crosses the RPC boundary: `packages/rpc`, `packages/workspace`, the `wsd` client, or the Durable Object server. |
29
29
|[`cloudflare`](.agents/skills/cloudflare/SKILL.md)| Index of host-side Cloudflare skills — Workers, Durable Objects, wrangler, sandbox SDK, agents SDK. |
30
30
31
+
## Environment setup
32
+
33
+
A fresh container does not have everything the tests need. The traps
34
+
below cost real time if you discover them one failure at a time.
35
+
36
+
**Native build tools.**`packages/wsd` depends on `fuse-native`, a
37
+
native addon. Building it needs a C toolchain and the libfuse2 headers.
38
+
On Debian or Ubuntu:
39
+
40
+
```bash
41
+
apt-get install build-essential libfuse-dev
42
+
```
43
+
44
+
If the `fuse-native` build fails, `npm install` aborts the whole
45
+
install, not just that one package. When you only need the rest of the
46
+
workspace, install with `npm install --ignore-scripts` to skip the
47
+
native build.
48
+
49
+
**arm64 hosts.**`fuse-native` ships a prebuilt libfuse for x64 only.
50
+
On a Linux arm64 host or container (including a Linux container on
51
+
Apple Silicon, or arm64 CI) the link fails with `file in wrong
52
+
format`. The path below is Debian or Ubuntu arm64; a native macOS host
53
+
uses macFUSE instead and does not hit this. Replace the bundled library
Every file and directory on the `wsd` FUSE mount reports zero disk usage. Writing twelve bytes and asking `du` for the size returns `0`:
2
+
3
+
```sh
4
+
printf'hello world\n'> /workspace/du-repro.txt
5
+
stat -c 'size=%s blocks=%b' /workspace/du-repro.txt
6
+
# size=12 blocks=0
7
+
du -B1 /workspace/du-repro.txt
8
+
# 0 /workspace/du-repro.txt
9
+
```
10
+
11
+
This is not a `du` bug. `du` reads `st_blocks` from `stat(2)`, not `st_size`, and the FUSE driver was leaving `st_blocks` empty. The `getattr` path built its stat result without the `blocks` and `blksize` fields, so the kernel saw zero allocated blocks for every inode on the mount.
12
+
13
+
The fix populates both fields wherever the driver builds a stat. `st_blocks` counts allocation in fixed 512-byte units, the unit POSIX defines for that field regardless of the filesystem's logical block size, so a 513-byte file occupies two blocks and an empty file occupies none. `st_blksize` is the preferred input/output size, a separate value that stays at `4096` to match what `statfs` already advertises and what the backing virtual filesystem reports. The backing filesystem already supplies both fields for files written to disk, so the driver passes those through and only derives the values for the in-memory cases: a freshly created file before its first flush, and a file whose buffered size has outrun the size on disk.
14
+
15
+
Reviewers with a privileged FUSE-capable container can verify the behavior against a real mount:
16
+
17
+
```sh
18
+
printf'hello world\n'> /workspace/du-repro.txt
19
+
stat -c 'size=%s blocks=%b' /workspace/du-repro.txt
20
+
# size=12 blocks=1
21
+
du -B1 /workspace/du-repro.txt
22
+
# 512 /workspace/du-repro.txt
23
+
```
24
+
25
+
The regression tests cover the same block accounting without requiring a mount. They assert block counts for a 513-byte file, an empty file, a freshly created file that has not flushed, and a file whose buffered size has grown past a block boundary before flush. These tests fail against the old stat shape because `blocks` and `blksize` are missing, and pass with this change.
26
+
27
+
This also updates the setup documentation around running the tests from a clean container. `AGENTS.md` now calls out the native build tools `fuse-native` needs, the Linux arm64 libfuse swap needed when the package's bundled x64 library cannot link, the need to build sibling package output before running tests, and the different gates used by the two real-FUSE test suites. The `packages/wsd` README no longer claims that its test script builds first or uses Node's type stripping; it describes the Vitest command, the required build output, and the difference between the `/dev/fuse`-guarded CLI test and the Docker-backed real-FUSE runner test.
Copy file name to clipboardExpand all lines: packages/wsd/README.md
+6-2Lines changed: 6 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -135,13 +135,17 @@ Caveats. The shim is dev-only:
135
135
136
136
## Tests
137
137
138
-
Tests live next to the source files and are written in TypeScript. The package test script builds first, then runs Node's experimental TypeScript stripping:
138
+
Tests live next to the source files and are written in TypeScript. Vitest runs them directly:
139
139
140
140
```sh
141
141
npm test --workspace=@cloudflare/workspace-wsd
142
142
```
143
143
144
-
This package requires Node.js 22+ because `@platformatic/vfs` does, and because the test script uses `--experimental-strip-types`, which is only available on Node 22+ (unflagged on 23.6+).
144
+
The test command does not build first. Some suites need build output that is not there in a clean checkout: the tests import the sibling `@cloudflare/dofs` and `@cloudflare/workspace-rpc` packages from their `dist/` directories, and `src/cli/wsd.test.ts` spawns the bundled CLI at `dist/cli/wsd.cjs`. Run `npm run build` across the workspace before `npm test`, or those tests fail to resolve the imports or exit early with no bundle to spawn.
145
+
146
+
This package requires Node.js 22+ because `@platformatic/vfs` does.
147
+
148
+
The two real-FUSE suites gate themselves differently. `src/cli/wsd.test.ts` runs its real-FUSE case only when `/dev/fuse` is reachable; otherwise auto-detection resolves to the shim and the case skips. The guard is a bare existence check, so a `mknod`'d `/dev/fuse` in an unprivileged container defeats the skip and the mount then fails with `EPERM` — leave the device absent unless the container is privileged (`--privileged`, or `CAP_SYS_ADMIN` with device access). `src/exec/runner.fuse.test.ts` is separate: it skips unless both Docker and the prebuilt `wsd` binary are available, and runs `wsd` inside a privileged container, so the host's `/dev/fuse` does not matter. See the [`debugging-wsd-fuse`](../../.agents/skills/debugging-wsd-fuse/SKILL.md) skill for the privileged Docker setup.
0 commit comments