forked from TrueCloudLab/restic
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
This commit is contained in:
parent
c5763e59d5
commit
5494c1858e
1 changed files with 13 additions and 6 deletions
|
@ -36,6 +36,7 @@ type SnapshotsDir struct {
|
||||||
// knownSnapshots maps snapshot timestamp to the snapshot
|
// knownSnapshots maps snapshot timestamp to the snapshot
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
knownSnapshots map[string]SnapshotWithId
|
knownSnapshots map[string]SnapshotWithId
|
||||||
|
processed restic.IDSet
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSnapshotsDir returns a new dir object for the snapshots.
|
// NewSnapshotsDir returns a new dir object for the snapshots.
|
||||||
|
@ -45,6 +46,7 @@ func NewSnapshotsDir(repo restic.Repository, ownerIsRoot bool) *SnapshotsDir {
|
||||||
repo: repo,
|
repo: repo,
|
||||||
knownSnapshots: make(map[string]SnapshotWithId),
|
knownSnapshots: make(map[string]SnapshotWithId),
|
||||||
ownerIsRoot: ownerIsRoot,
|
ownerIsRoot: ownerIsRoot,
|
||||||
|
processed: restic.NewIDSet(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +68,11 @@ func (sn *SnapshotsDir) updateCache(ctx context.Context) error {
|
||||||
defer sn.Unlock()
|
defer sn.Unlock()
|
||||||
|
|
||||||
for id := range sn.repo.List(restic.SnapshotFile, ctx.Done()) {
|
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())
|
debug.Log("SnapshotsDir.List", "found snapshot id %v", id.Str())
|
||||||
snapshot, err := restic.LoadSnapshot(sn.repo, id)
|
snapshot, err := restic.LoadSnapshot(sn.repo, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -73,7 +80,6 @@ func (sn *SnapshotsDir) updateCache(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
timestamp := snapshot.Time.Format(time.RFC3339)
|
timestamp := snapshot.Time.Format(time.RFC3339)
|
||||||
|
|
||||||
for i := 1; ; i++ {
|
for i := 1; ; i++ {
|
||||||
if _, ok := sn.knownSnapshots[timestamp]; !ok {
|
if _, ok := sn.knownSnapshots[timestamp]; !ok {
|
||||||
break
|
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)
|
debug.Log("SnapshotsDir.List", " add %v as dir %v", id.Str(), timestamp)
|
||||||
sn.knownSnapshots[timestamp] = SnapshotWithId{snapshot, id}
|
sn.knownSnapshots[timestamp] = SnapshotWithId{snapshot, id}
|
||||||
|
sn.processed.Insert(id)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -107,11 +114,11 @@ func (sn *SnapshotsDir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
|
||||||
defer sn.RUnlock()
|
defer sn.RUnlock()
|
||||||
|
|
||||||
ret := make([]fuse.Dirent, 0)
|
ret := make([]fuse.Dirent, 0)
|
||||||
for _, snapshot := range sn.knownSnapshots {
|
for timestamp, snapshot := range sn.knownSnapshots {
|
||||||
ret = append(ret, fuse.Dirent{
|
ret = append(ret, fuse.Dirent{
|
||||||
Inode: inodeFromBackendID(snapshot.ID),
|
Inode: inodeFromBackendID(snapshot.ID),
|
||||||
Type: fuse.DT_Dir,
|
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) {
|
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)
|
snapshot, ok := sn.get(name)
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
// We don't know about it, update the cache
|
// We don't know about it, update the cache
|
||||||
err := sn.updateCache(ctx)
|
err := sn.updateCache(ctx)
|
||||||
if err != nil {
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
snapshot, ok = sn.get(name)
|
snapshot, ok = sn.get(name)
|
||||||
if !ok {
|
if !ok {
|
||||||
// We still don't know about it, this time it really doesn't exist
|
// 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
|
return nil, fuse.ENOENT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue