mirror of
https://github.com/restic/restic.git
synced 2026-06-27 19:14:18 +00:00
55e335ec6c
The treeCache in SnapshotsDir was never cleared when snapshots were reloaded. This caused the "latest" symlink to keep pointing to the previous snapshot even after new snapshots were added. Add a generation counter to SnapshotsDirStructure that is incremented whenever the directory structure is rebuilt (in makeDirs). The treeCache checks this generation on each lookup and resets itself when the generation changes, ensuring cached nodes (including symlinks) are refreshed after a snapshot reload.
57 lines
1.0 KiB
Go
57 lines
1.0 KiB
Go
//go:build darwin || freebsd || linux
|
|
|
|
package fuse
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/restic/restic/internal/debug"
|
|
|
|
"github.com/anacrolix/fuse/fs"
|
|
)
|
|
|
|
type treeCache struct {
|
|
nodes map[string]fs.Node
|
|
m sync.Mutex
|
|
generation int64
|
|
}
|
|
|
|
type forgetFn func()
|
|
|
|
func newTreeCache() *treeCache {
|
|
return &treeCache{
|
|
nodes: map[string]fs.Node{},
|
|
}
|
|
}
|
|
|
|
func (t *treeCache) lookupOrCreate(name string, generation int64, create func(forget forgetFn) (fs.Node, error)) (fs.Node, error) {
|
|
t.m.Lock()
|
|
defer t.m.Unlock()
|
|
|
|
if generation >= 0 && generation != t.generation {
|
|
debug.Log("treeCache generation changed %d -> %d, resetting cache", t.generation, generation)
|
|
t.nodes = make(map[string]fs.Node)
|
|
t.generation = generation
|
|
}
|
|
|
|
if node, ok := t.nodes[name]; ok {
|
|
return node, nil
|
|
}
|
|
|
|
cacheGeneration := t.generation
|
|
node, err := create(func() {
|
|
t.m.Lock()
|
|
defer t.m.Unlock()
|
|
|
|
if t.generation == cacheGeneration {
|
|
delete(t.nodes, name)
|
|
}
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
t.nodes[name] = node
|
|
return node, nil
|
|
}
|