mount: keep flushing an open file whose other hard link survives an unlink

Unlink marks the inode's open handle deleted so no flush recreates the
removed name. When the entry was one of several hard links the inode lives
on under another name, yet the mark stayed and every later fsync and close
returned OK without publishing metadata. Lift the unlink's own mark once
the name is gone and the inode still has a path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Chris LuandClaude Opus 5.5 committed 2026-11-13 01:09:29 -08:00
1 parent a576398662
commit b892d619b9
1 file changed
+15 -5
+15 -5
View File
@@ -286,13 +286,15 @@ func (wfs *WFS) Unlink(cancel <-chan struct{}, header *fuse.InHeader, name strin
// before Unlink sets the flag). By waiting here, any in-flight flush
// finishes first; even if it recreated the entry, the filer delete below
// will remove it again.
var markedInode, deleteEpoch uint64
if inode, found := wfs.inodeToPath.GetInode(entryFullPath); found {
wfs.markHandleDeleted(inode)
wfs.waitForPendingAsyncFlush(context.Background(), inode)
markedInode = inode
} else if entry != nil && entry.Attributes != nil && entry.Attributes.Inode != 0 {
inodeFromEntry := entry.Attributes.Inode
wfs.markHandleDeleted(inodeFromEntry)
wfs.waitForPendingAsyncFlush(context.Background(), inodeFromEntry)
markedInode = entry.Attributes.Inode
}
if markedInode != 0 {
deleteEpoch = wfs.markHandleDeleted(markedInode)
wfs.waitForPendingAsyncFlush(context.Background(), markedInode)
}
// first, ensure the filer store can correctly delete
@@ -355,6 +357,14 @@ func (wfs *WFS) Unlink(cancel <-chan struct{}, header *fuse.InHeader, name strin
wfs.syncHardLinkSiblings(ctx, sharedInode, decremented, event.GetTsNs(), entryFullPath)
}
// Another link still names the inode, so its open handle keeps flushing
// through that name.
if isHardLink && markedInode != 0 {
if _, status := wfs.inodeToPath.GetPath(markedInode); status == fuse.OK {
wfs.clearHandleDeleted(markedInode, deleteEpoch)
}
}
return fuse.OK
}