Skip to content

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

@melvincarvalho

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions