From 5494c1858e159189b3e3706ca0749862c6e636bc Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sun, 18 Sep 2016 15:03:14 +0200 Subject: [PATCH] fuse: correctly handle snapshots The fuse code kept adding snapshots to the top-level dir "snapshots". In addition, snapshots with the same timestamp (same second) were not added correctly, they will now be suffixed by an incrementing counter, e.g.: dr-xr-xr-x 1 fd0 users 0 Sep 18 15:01 2016-09-18T15:01:44+02:00 dr-xr-xr-x 1 fd0 users 0 Sep 18 15:01 2016-09-18T15:01:48+02:00 dr-xr-xr-x 1 fd0 users 0 Sep 18 15:01 2016-09-18T15:01:48+02:00-1 Closes #624 --- src/restic/fuse/snapshot.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/restic/fuse/snapshot.go b/src/restic/fuse/snapshot.go index 9270e9adc..c157177ec 100644 --- a/src/restic/fuse/snapshot.go +++ b/src/restic/fuse/snapshot.go @@ -36,6 +36,7 @@ type SnapshotsDir struct { // knownSnapshots maps snapshot timestamp to the snapshot sync.RWMutex knownSnapshots map[string]SnapshotWithId + processed restic.IDSet } // NewSnapshotsDir returns a new dir object for the snapshots. @@ -45,6 +46,7 @@ func NewSnapshotsDir(repo restic.Repository, ownerIsRoot bool) *SnapshotsDir { repo: repo, knownSnapshots: make(map[string]SnapshotWithId), ownerIsRoot: ownerIsRoot, + processed: restic.NewIDSet(), } } @@ -66,6 +68,11 @@ func (sn *SnapshotsDir) updateCache(ctx context.Context) error { defer sn.Unlock() for id := range sn.repo.List(restic.SnapshotFile, ctx.Done()) { + if sn.processed.Has(id) { + debug.Log("SnapshotsDir.List", "skipping snapshot %v, already in list", id.Str()) + continue + } + debug.Log("SnapshotsDir.List", "found snapshot id %v", id.Str()) snapshot, err := restic.LoadSnapshot(sn.repo, id) if err != nil { @@ -73,7 +80,6 @@ func (sn *SnapshotsDir) updateCache(ctx context.Context) error { } timestamp := snapshot.Time.Format(time.RFC3339) - for i := 1; ; i++ { if _, ok := sn.knownSnapshots[timestamp]; !ok { break @@ -84,6 +90,7 @@ func (sn *SnapshotsDir) updateCache(ctx context.Context) error { debug.Log("SnapshotsDir.List", " add %v as dir %v", id.Str(), timestamp) sn.knownSnapshots[timestamp] = SnapshotWithId{snapshot, id} + sn.processed.Insert(id) } return nil } @@ -107,11 +114,11 @@ func (sn *SnapshotsDir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { defer sn.RUnlock() ret := make([]fuse.Dirent, 0) - for _, snapshot := range sn.knownSnapshots { + for timestamp, snapshot := range sn.knownSnapshots { ret = append(ret, fuse.Dirent{ Inode: inodeFromBackendID(snapshot.ID), Type: fuse.DT_Dir, - Name: snapshot.Time.Format(time.RFC3339), + Name: timestamp, }) } @@ -120,20 +127,20 @@ func (sn *SnapshotsDir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { } func (sn *SnapshotsDir) Lookup(ctx context.Context, name string) (fs.Node, error) { - debug.Log("SnapshotsDir.updateCache", "Lookup(%s)", name) + debug.Log("SnapshotsDir.Lookup", "Lookup(%s)", name) snapshot, ok := sn.get(name) if !ok { // We don't know about it, update the cache err := sn.updateCache(ctx) if err != nil { - debug.Log("SnapshotsDir.updateCache", " Lookup(%s) -> err %v", name, err) + debug.Log("SnapshotsDir.Lookup", " Lookup(%s) -> err %v", name, err) return nil, err } snapshot, ok = sn.get(name) if !ok { // We still don't know about it, this time it really doesn't exist - debug.Log("SnapshotsDir.updateCache", " Lookup(%s) -> not found", name) + debug.Log("SnapshotsDir.Lookup", " Lookup(%s) -> not found", name) return nil, fuse.ENOENT } }