Skip to content

fs.stat: a symlink's size is its stored object length (target + 27 bytes); is the target length intended? #447

Closed

Description

@leepokai

Summary

fs.stat reports a symlink's size as the length of the canonical object that stores its target, not as the target's length. That object holds the target plus the object envelope (LFSO, 13 bytes) and the symlink header (LFS4LNK, 14 bytes), so every symlink comes out 27 bytes too large. A mounted Workspace reports the target's length, and so does the source folder Init read from, which means the SDK and the mount disagree about the same symlink.

Repro

Run on Linux against current main (c77281e49) with the real addon and a Disposable Store. Init a folder holding link -> a.txt and dangling -> /does/not/exist, then call:

fs.stat("main", "/link")      -> { type: "symlink", size: 32 }   // expected 5
fs.stat("main", "/dangling")  -> { type: "symlink", size: 42 }   // expected 15

ls -l in the source folder shows 5 and 15. Under a real FUSE mount (the kernel_mount fixture's five symlinks), lstat size equals the readlink length for each one.

Cause

For InodeKind::Symlink, size() in layerfs-store-service/src/read/snapshot.rs returns read_canonical(content_root).len(). The Workspace base view does it differently: stat_resolved_with_lengths in layerfs-workspace/src/base/view.rs decodes the object with SymlinkTarget::decode and uses as_bytes().len(), and the FUSE attributes take that value. The operator file history and stats also call size(), so they count symlinks 27 bytes too large as well.

Why I think the target length is intended

If the canonical length is what fs.stat should report, I can change the PR to document that instead.

Expected

A symlink's fs.stat size is its target's byte length, the same as the mount reports.

Fix with a regression test: #448.

Activity

  1. leepokai commented on Oct 24, 2026

    @leepokai
    ContributorAuthor

    Two more data points, both from the repository's history:

  2. added a commit that references this issue on Oct 26, 2026
  3. yifanxuaaa commented on Oct 26, 2026

    @yifanxuaaa
    Contributor

    Fixed on main by 3828268 (merge of #448): fs.stat now reports a symlink's size as its target length, the same as lstat in a mounted Workspace. The operator storage and revision answers count symlinks the same way.

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

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