From 04c042756a3bf3114a3e0a7773d0943528c4d1ab Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 23 Aug 2022 22:20:35 -0600 Subject: Factor rebuildmappings.MapLogicalSums out of inspect_dbgsums --- .../btrfsinspect/rebuildmappings/csumitems.go | 92 ++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 lib/btrfsprogs/btrfsinspect/rebuildmappings/csumitems.go (limited to 'lib') diff --git a/lib/btrfsprogs/btrfsinspect/rebuildmappings/csumitems.go b/lib/btrfsprogs/btrfsinspect/rebuildmappings/csumitems.go new file mode 100644 index 0000000..90a15b0 --- /dev/null +++ b/lib/btrfsprogs/btrfsinspect/rebuildmappings/csumitems.go @@ -0,0 +1,92 @@ +// Copyright (C) 2022 Luke Shumaker +// +// SPDX-License-Identifier: GPL-2.0-or-later + +package rebuildmappings + +import ( + "context" + "strings" + + "github.com/datawire/dlib/dlog" + + "git.lukeshu.com/btrfs-progs-ng/lib/btrfs" + "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfssum" + "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol" + "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsinspect" + "git.lukeshu.com/btrfs-progs-ng/lib/maps" +) + +func MapLogicalSums(ctx context.Context, scanResults btrfsinspect.ScanDevicesResult) btrfssum.SumRunWithGaps[btrfsvol.LogicalAddr] { + dlog.Info(ctx, "Mapping the logical address space...") + type record struct { + Gen btrfs.Generation + Sum btrfssum.ShortSum + } + addrspace := make(map[btrfsvol.LogicalAddr]record) + var sumSize int + for _, devResults := range scanResults { + sumSize = devResults.Checksums.ChecksumSize + for _, sumItem := range devResults.FoundExtentCSums { + _ = sumItem.Sums.Walk(ctx, func(pos btrfsvol.LogicalAddr, sum btrfssum.ShortSum) error { + new := record{ + Gen: sumItem.Generation, + Sum: sum, + } + if old, ok := addrspace[pos]; ok { + switch { + case old.Gen > new.Gen: + // do nothing + case old.Gen < new.Gen: + addrspace[pos] = new + case old.Gen == new.Gen: + if old != new { + dlog.Errorf(ctx, "mismatch of laddr=%v sum: %v != %v", pos, old, new) + } + } + } else { + addrspace[pos] = new + } + return nil + }) + } + } + dlog.Info(ctx, "... done mapping") + + var flattened btrfssum.SumRunWithGaps[btrfsvol.LogicalAddr] + if len(addrspace) == 0 { + return flattened + } + + dlog.Info(ctx, "Flattening the map ...") + var curAddr btrfsvol.LogicalAddr + var curSums strings.Builder + for _, laddr := range maps.SortedKeys(addrspace) { + if laddr != curAddr+(btrfsvol.LogicalAddr(curSums.Len()/sumSize)*btrfssum.BlockSize) { + if curSums.Len() > 0 { + flattened.Runs = append(flattened.Runs, btrfssum.SumRun[btrfsvol.LogicalAddr]{ + ChecksumSize: sumSize, + Addr: curAddr, + Sums: btrfssum.ShortSum(curSums.String()), + }) + } + curAddr = laddr + curSums.Reset() + } + curSums.WriteString(string(addrspace[laddr].Sum)) + } + if curSums.Len() > 0 { + flattened.Runs = append(flattened.Runs, btrfssum.SumRun[btrfsvol.LogicalAddr]{ + ChecksumSize: sumSize, + Addr: curAddr, + Sums: btrfssum.ShortSum(curSums.String()), + }) + } + flattened.Addr = flattened.Runs[0].Addr + last := flattened.Runs[len(flattened.Runs)-1] + end := last.Addr.Add(last.Size()) + flattened.Size = end.Sub(flattened.Addr) + dlog.Info(ctx, "... done flattening") + + return flattened +} -- cgit v1.2.3-2-g168b