fuse: cache fs.Node instances

A particular node should always be represented by a single instance.
This is necessary to allow the fuse library to assign a stable nodeId to
a node. macOS Sonoma trips over the previous, unstable behavior when
using fuse-t.
This commit is contained in:
Michael Eischer
2024-09-09 22:15:30 +02:00
parent c1532179d4
commit 6ec2b62ec5
3 changed files with 71 additions and 24 deletions

View File

@@ -23,6 +23,7 @@ type SnapshotsDir struct {
parentInode uint64
dirStruct *SnapshotsDirStructure
prefix string
cache treeCache
}
// ensure that *SnapshotsDir implements these interfaces
@@ -38,6 +39,7 @@ func NewSnapshotsDir(root *Root, inode, parentInode uint64, dirStruct *Snapshots
parentInode: parentInode,
dirStruct: dirStruct,
prefix: prefix,
cache: *newTreeCache(),
}
}
@@ -107,8 +109,12 @@ func (d *SnapshotsDir) Lookup(ctx context.Context, name string) (fs.Node, error)
return nil, syscall.ENOENT
}
entry := meta.names[name]
if entry != nil {
return d.cache.lookupOrCreate(name, func() (fs.Node, error) {
entry := meta.names[name]
if entry == nil {
return nil, syscall.ENOENT
}
inode := inodeFromName(d.inode, name)
if entry.linkTarget != "" {
return newSnapshotLink(d.root, inode, entry.linkTarget, entry.snapshot)
@@ -116,9 +122,7 @@ func (d *SnapshotsDir) Lookup(ctx context.Context, name string) (fs.Node, error)
return newDirFromSnapshot(d.root, inode, entry.snapshot)
}
return NewSnapshotsDir(d.root, inode, d.inode, d.dirStruct, d.prefix+"/"+name), nil
}
return nil, syscall.ENOENT
})
}
// SnapshotLink