1
0
Fork 0
mirror of https://github.com/restic/restic.git synced 2024-12-23 08:16:36 +00:00

fuse: Better check for whether snapshots changed

We previously checked whether the set of snapshots might have changed
based only on their number, which fails when as many snapshots are
forgotten as are added. Check for the SHA-256 of their id's instead.
This commit is contained in:
greatroar 2022-11-02 22:23:14 +01:00
parent 59a90943bb
commit c091e43b33

View file

@ -4,6 +4,7 @@
package fuse package fuse
import ( import (
"bytes"
"context" "context"
"fmt" "fmt"
"path" "path"
@ -14,6 +15,8 @@ import (
"github.com/restic/restic/internal/debug" "github.com/restic/restic/internal/debug"
"github.com/restic/restic/internal/restic" "github.com/restic/restic/internal/restic"
"github.com/minio/sha256-simd"
) )
type MetaDirData struct { type MetaDirData struct {
@ -39,7 +42,7 @@ type SnapshotsDirStructure struct {
// that way we don't need path processing special cases when using the entries tree // that way we don't need path processing special cases when using the entries tree
entries map[string]*MetaDirData entries map[string]*MetaDirData
snCount int hash [sha256.Size]byte // Hash at last check.
lastCheck time.Time lastCheck time.Time
} }
@ -49,7 +52,6 @@ func NewSnapshotsDirStructure(root *Root, pathTemplates []string, timeTemplate s
root: root, root: root,
pathTemplates: pathTemplates, pathTemplates: pathTemplates,
timeTemplate: timeTemplate, timeTemplate: timeTemplate,
snCount: -1,
} }
} }
@ -302,10 +304,26 @@ func (d *SnapshotsDirStructure) updateSnapshots(ctx context.Context) error {
if err != nil { if err != nil {
return err return err
} }
// sort snapshots ascending by time (default order is descending)
sort.Sort(sort.Reverse(snapshots))
if d.snCount == len(snapshots) { // Sort snapshots ascending by time, using the id to break ties.
// This needs to be done before hashing.
sort.Slice(snapshots, func(i, j int) bool {
si, sj := snapshots[i], snapshots[j]
if si.Time.Equal(sj.Time) {
return bytes.Compare(si.ID()[:], sj.ID()[:]) < 0
}
return si.Time.Before(sj.Time)
})
// We update the snapshots when the hash of their id's changes.
h := sha256.New()
for _, sn := range snapshots {
h.Write(sn.ID()[:])
}
var hash [sha256.Size]byte
h.Sum(hash[:0])
if d.hash == hash {
d.lastCheck = time.Now() d.lastCheck = time.Now()
return nil return nil
} }
@ -316,7 +334,7 @@ func (d *SnapshotsDirStructure) updateSnapshots(ctx context.Context) error {
} }
d.lastCheck = time.Now() d.lastCheck = time.Now()
d.snCount = len(snapshots) d.hash = hash
d.makeDirs(snapshots) d.makeDirs(snapshots)
return nil return nil
} }