Summary
The do_link function in the overlayfs implementation incorrectly allocates new inode numbers for hard links instead of reusing the source file's inode number, violating POSIX hard link semantics.
Problem
When creating a hard link using the do_link function (lines 1506-1605), the code always allocates a new inode number:
// Line 1583-1585
let path = format!("{}/{}", new_parent.path, name);
let ino = self.alloc_inode(&path)?; // ❌ Wrong: allocates NEW inode
let child_ri = parent_real_inode.link(ctx, src_ino, name)?;
Expected vs Actual Behavior
| Aspect |
Expected |
Actual |
| Source file inode |
100 |
100 |
| Hard link inode |
100 (same) |
101 (different) |
| POSIX compliance |
✅ |
❌ |
Impact
- File system integrity: Applications checking
st_ino will see different inodes for the same file
- Backup tools:
rsync, tar and similar tools will fail to detect hard links
- Deduplication: Storage space will be incorrectly calculated
- Application bugs: Any software relying on inode equality for hard link detection will malfunction
Root Cause
The issue is in the None branch of the match statement where a completely new OverlayInode is created with a new inode number instead of reusing the source file's inode.
Fix Required
Replace:
let ino = self.alloc_inode(&path)?;
With:
let ino = src_node.inode; // Reuse source inode number
Note: This fix requires careful handling of the inode store's path mapping and reference counting to avoid conflicts.
Reproduction
// Create file
let file_entry = fs.create(parent, "file.txt", args)?;
let original_ino = file_entry.inode;
// Create hard link
fs.link(original_ino, parent, "link.txt")?;
let link_entry = fs.lookup(parent, "link.txt")?;
// BUG: These should be equal but are different
assert_eq!(original_ino, link_entry.inode); // ❌ Fails
This is a critical bug that breaks fundamental filesystem semantics and should be prioritized for fixing.
Summary
The
do_linkfunction in the overlayfs implementation incorrectly allocates new inode numbers for hard links instead of reusing the source file's inode number, violating POSIX hard link semantics.Problem
When creating a hard link using the
do_linkfunction (lines 1506-1605), the code always allocates a new inode number:Expected vs Actual Behavior
Impact
st_inowill see different inodes for the same filersync,tarand similar tools will fail to detect hard linksRoot Cause
The issue is in the
Nonebranch of thematchstatement where a completely newOverlayInodeis created with a new inode number instead of reusing the source file's inode.Fix Required
Replace:
With:
Note: This fix requires careful handling of the inode store's path mapping and reference counting to avoid conflicts.
Reproduction
This is a critical bug that breaks fundamental filesystem semantics and should be prioritized for fixing.