mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-11-13 15:29:12 +01:00
mount: record a hard link's looked-up names on its inode
Lookup mapped a second name of a hard-linked file to the existing inode without adding it to the inode's names, so GetAllPaths missed it and the final forget left it mapped to a released inode. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c851066f79
commit
70d6639155
2 files changed
+28
-2
No files matched your search
@@ -201,9 +201,13 @@ func (i *InodeToPath) Lookup(path util.FullPath, unixTime int64, isDirectory boo
|
||||
}
|
||||
i.path2inode[path] = inode
|
||||
|
||||
if _, found := i.inode2path[inode]; found {
|
||||
if ie, known := i.inode2path[inode]; known {
|
||||
// Another name of a hard link the table already holds.
|
||||
if !found {
|
||||
ie.addPath(path)
|
||||
}
|
||||
if isLookup {
|
||||
i.inode2path[inode].nlookup++
|
||||
ie.nlookup++
|
||||
}
|
||||
} else {
|
||||
nlookup := uint64(0)
|
||||
|
||||
@@ -208,3 +208,25 @@ func TestMovePathWithNoSourceLeavesTheTarget(t *testing.T) {
|
||||
t.Errorf("/a/g.txt resolves to %d (found %v), want %d", got, found, inode)
|
||||
}
|
||||
}
|
||||
|
||||
// A second hard link name found by a lookup belongs to the inode, so it is
|
||||
// reported with the others and released by the final forget.
|
||||
func TestLookupRecordsHardLinkNames(t *testing.T) {
|
||||
table := NewInodeToPath(util.FullPath("/"), 0)
|
||||
inode := table.Lookup("/a", 1, false, true, 42, true)
|
||||
if got := table.Lookup("/b", 1, false, true, 42, true); got != inode {
|
||||
t.Fatalf("second name got inode %d, want %d", got, inode)
|
||||
}
|
||||
table.Lookup("/b", 1, false, true, 42, true)
|
||||
if got := table.GetAllPaths(inode); len(got) != 2 || got[0] != "/a" || got[1] != "/b" {
|
||||
t.Fatalf("paths %v, want [/a /b]", got)
|
||||
}
|
||||
table.RemovePath("/a", nil)
|
||||
if got, status := table.GetPath(inode); status != fuse.OK || got != "/b" {
|
||||
t.Fatalf("after removing /a the inode answers to %q (%v), want /b", got, status)
|
||||
}
|
||||
table.Forget(inode, 3, nil, nil)
|
||||
if _, found := table.GetInode("/b"); found {
|
||||
t.Fatal("the final forget left /b mapped to a released inode")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user