mirror of
https://github.com/restic/restic.git
synced 2026-06-27 02:54:19 +00:00
fuse: reset treeCache on snapshot reload to fix stale latest symlink (#21873)
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.
This commit is contained in:
committed by
Michael Eischer
parent
add4fa1efb
commit
32be2e559b
@@ -5,12 +5,15 @@ 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
|
||||
nodes map[string]fs.Node
|
||||
m sync.Mutex
|
||||
generation int64
|
||||
}
|
||||
|
||||
type forgetFn func()
|
||||
@@ -21,19 +24,28 @@ func newTreeCache() *treeCache {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *treeCache) lookupOrCreate(name string, create func(forget forgetFn) (fs.Node, error)) (fs.Node, error) {
|
||||
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()
|
||||
|
||||
delete(t.nodes, name)
|
||||
if t.generation == cacheGeneration {
|
||||
delete(t.nodes, name)
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user