Skip to content

Solid-native filesystem mount — FUSE driver with ACL / notifications / JSON-LD as first-class #508

Description

@melvincarvalho

Why

The companion to #507. That issue wraps Solid behind WebDAV — universal but loses Solid's distinctive features. This one exposes Solid natively: a FUSE filesystem driver that speaks Solid as its native protocol and surfaces what makes Solid Solid.

The pitch: this is the mount that lets getfattr -n user.solid.acl /mnt/alice/diary.md return the actual ACL doc, and lets inotifywait /mnt/alice/inbox/ block on the pod's real-time /.notifications stream. Once these become filesystem-native, every tool that knows about xattrs and inotify (Nautilus included) inherits the integration for free.

Shape

solidfs mount https://alice.solidcommunity.net /mnt/alice
fusermount -u /mnt/alice

Standard FUSE ops on top of Solid HTTP:

  • getattr → HEAD upstream, cache briefly
  • readdir → GET with Accept: application/ld+json, parse ldp:contains
  • read → GET with Range
  • write → buffer + PUT on flush (or chunked via PATCH if the server supports it)
  • create → PUT empty body with content-type from filename
  • unlink → DELETE
  • mkdir → LDP POST with Slug + Link: <ldp#BasicContainer>
  • rmdir → walk + DELETE (LDP needs empty containers)
  • rename → GET + PUT + DELETE (LDP has no MOVE)

Solid features as first-class filesystem properties:

Solid concept FS surface
Container Directory
Resource File
ACL (<r>.acl) xattr user.solid.acl (read/write the JSON-LD doc)
WAC-Allow xattr user.solid.permissions (effective modes for current identity)
JSON-LD @type xattr user.solid.type
/.notifications WS inotify events on the mountpoint
Solid-OIDC identity xattr user.solid.webid at mount root
Cross-pod link symlink with magic target solid://<url>

Bonus once notifications are wired: Nautilus auto-refreshes when a collaborator writes a file. No explicit reload.

Tradeoffs

  • ✓ Solid features (ACL, types, notifications) are first-class, not lost in translation
  • ✓ Better performance (no protocol shim)
  • ✓ Standard Unix tools (stat, getfattr, inotifywait, find) just work
  • ✗ Linux + macOS only out of the box (Windows needs WinFsp shim — possible but more work)
  • ✗ Higher complexity than WebDAV; needs FUSE kernel module on Linux, macFUSE on macOS
  • ✗ Distribution friction: Node + fuse-native bindings, or a Rust/Go binary

Implementation options

  1. Node + fuse-native — sits in the same ecosystem as JSS; cheapest spike. Performance OK for most uses.
  2. Rust + fuser crate — production-quality, fast, single static binary. Better for rsync-of-pod scale.
  3. Go + bazil.org/fuse — middle ground, good cross-compile story.

Node first is probably right: prove the model, then port hot paths if needed.

Open questions

  • Caching policy: getattr fires per-stat; need short-TTL cache (~1s) plus invalidation on notifications.
  • Write semantics: write-on-flush vs streaming. Solid PUT is whole-resource, so partial writes need buffering. Big files = big memory unless we PATCH (server-dependent).
  • ACL edits via xattr: writing user.solid.acl should PUT to <resource>.acl. Clean API but a footgun if user pastes broken JSON.
  • Auth refresh in long-lived mounts: same issue as the WebDAV bridge — needs a quiet renewal loop.
  • Notifications → inotify mapping: pod events are JSON-LD; need a translation layer to IN_CREATE / IN_MODIFY / IN_DELETE.

Effort

~2000-3000 LOC for a first cut. Bigger than the WebDAV bridge but each line bought back is a Solid feature that survives the round trip.

Naming

solidfs or solid-mount. solidfs is shorter and the established convention (sshfs, s3fs).

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions