Correct #2531 (`stats` restore-size calculates hard links incorrectly)

This commit is contained in:
David Potter 2020-01-07 17:05:16 -08:00 committed by Leo R. Lundgren
parent 23055aaadf
commit 71900248ab
2 changed files with 20 additions and 7 deletions

View File

@ -0,0 +1,5 @@
Bugfix: Fix incorrect size calculation in `stats --mode restore-size`
The restore-size mode of stats was counting hard-linked files as if they were independent.
https://github.com/restic/restic/issues/2531

View File

@ -89,10 +89,11 @@ func runStats(gopts GlobalOptions, args []string) error {
// create a container for the stats (and other needed state)
stats := &statsContainer{
uniqueFiles: make(map[fileID]struct{}),
fileBlobs: make(map[string]restic.IDSet),
blobs: restic.NewBlobSet(),
blobsSeen: restic.NewBlobSet(),
uniqueFiles: make(map[fileID]struct{}),
uniqueInodes: make(map[uint64]struct{}),
fileBlobs: make(map[string]restic.IDSet),
blobs: restic.NewBlobSet(),
blobsSeen: restic.NewBlobSet(),
}
if snapshotIDString != "" {
@ -249,9 +250,12 @@ func statsWalkTree(repo restic.Repository, stats *statsContainer) walker.WalkFun
// will still be restored
stats.TotalFileCount++
// TODO - Issue #2531 Handle hard links by identifying duplicate inodes.
// (Duplicates should appear in the file count, but not the size count)
stats.TotalSize += node.Size
// if inodes are present, only count each inode once
// (hard links do not increase restore size)
if _, ok := stats.uniqueInodes[node.Inode]; !ok || node.Inode == 0 {
stats.uniqueInodes[node.Inode] = struct{}{}
stats.TotalSize += node.Size
}
return false, nil
}
@ -306,6 +310,10 @@ type statsContainer struct {
// contents (hashed sequence of content blob IDs)
uniqueFiles map[fileID]struct{}
// uniqueInodes marks visited files according to their
// inode # (hashed sequence of inode numbers)
uniqueInodes map[uint64]struct{}
// fileBlobs maps a file name (path) to the set of
// blobs that have been seen as a part of the file
fileBlobs map[string]restic.IDSet