Skip to content

fix: propagate writes across hard links sharing the same inode#385

Draft
toddr-bot wants to merge 1 commit intocpan-authors:mainfrom
toddr-bot:koan.toddr.bot/fix-hardlink-shared-data
Draft

fix: propagate writes across hard links sharing the same inode#385
toddr-bot wants to merge 1 commit intocpan-authors:mainfrom
toddr-bot:koan.toddr.bot/fix-hardlink-shared-data

Conversation

@toddr-bot
Copy link
Copy Markdown
Collaborator

What

Hard link writes now propagate to all mocks sharing the same inode.

Why

link() copied contents as an independent scalar, so writing through one
hard link was invisible when reading through the other — violating POSIX
semantics where hard links share the same underlying data block.

How

Added _sync_hardlink_contents() that iterates same-inode mocks (same
pattern as the existing nlink propagation in unlink()) and syncs the
contents scalar. Called from three write paths:

  • FileHandle::_write_bytes() — after print/syswrite
  • contents() setter — covers truncate() and programmatic updates
  • __open truncation — the > / +> mode path that bypasses the setter

The sync is guarded by nlink > 1 so non-linked files pay zero cost.

Testing

7 new test cases in t/symlink_link.t:

  • Write through source visible via hard link
  • Write through hard link visible via source
  • Append mode propagation
  • syswrite propagation
  • Truncation via open('>') propagation
  • truncate() propagation
  • Three-way link propagation (A↔B↔C)

Full suite: 1594 tests pass (pre-existing fh-ref-leak.t failure excluded).

link() copied contents as an independent scalar, so writing to one
hard link was invisible through the other — violating POSIX semantics
where hard links share the same underlying data.

Add _sync_hardlink_contents() that propagates contents changes to all
mocks sharing the same inode. Called from FileHandle _write_bytes(),
the contents() setter, and __open truncation path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant