From 08f36346efae090737ff70b33b73e360d41a5856 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 17 Jul 2022 20:20:51 -0600 Subject: Make sure there's enough free space for gaps at the beginning or end of bgs --- .../btrfsinspect/scanforextents/csums.go | 36 ++++++++++------------ lib/btrfsprogs/btrfsinspect/scanforextents/scan.go | 16 ++++++---- 2 files changed, 26 insertions(+), 26 deletions(-) (limited to 'lib') diff --git a/lib/btrfsprogs/btrfsinspect/scanforextents/csums.go b/lib/btrfsprogs/btrfsinspect/scanforextents/csums.go index c1a1597..0ab933e 100644 --- a/lib/btrfsprogs/btrfsinspect/scanforextents/csums.go +++ b/lib/btrfsprogs/btrfsinspect/scanforextents/csums.go @@ -84,31 +84,30 @@ func (run SumRun[Addr]) Walk(ctx context.Context, fn func(Addr, ShortSum) error) // SumRunWithGaps //////////////////////////////////////////////////// -type SumRunWithGaps[Addr btrfsvol.IntAddr[Addr]] []SumRun[Addr] - -func (sg SumRunWithGaps[Addr]) end() Addr { - return sg[len(sg)-1].Addr.Add(sg[len(sg)-1].Size()) +type SumRunWithGaps[Addr btrfsvol.IntAddr[Addr]] struct { + Addr Addr + Size btrfsvol.AddrDelta + Runs []SumRun[Addr] } -func (sg SumRunWithGaps[Addr]) Size() btrfsvol.AddrDelta { - if len(sg) == 0 { - return 0 - } - return sg.end().Sub(sg[0].Addr) +func (sg SumRunWithGaps[Addr]) NumSums() int { + return int(sg.Size / CSumBlockSize) } -func (sg SumRunWithGaps[Addr]) NumSums() int { - return int(sg.Size() / CSumBlockSize) +func (sg SumRunWithGaps[Addr]) PctFull() float64 { + total := sg.NumSums() + var full int + for _, run := range sg.Runs { + full += run.NumSums() + } + return float64(full) / float64(total) } func (sg SumRunWithGaps[Addr]) SumForAddr(addr Addr) (ShortSum, error) { - if len(sg) == 0 { - return "", io.EOF - } - if addr < sg[0].Addr || addr >= sg.end() { + if addr < sg.Addr || addr >= sg.Addr.Add(sg.Size) { return "", io.EOF } - for _, run := range sg { + for _, run := range sg.Runs { if run.Addr > addr { return "", diskio.ErrWildcard } @@ -123,10 +122,7 @@ func (sg SumRunWithGaps[Addr]) SumForAddr(addr Addr) (ShortSum, error) { // Get implements diskio.Sequence[int, ShortSum] func (sg SumRunWithGaps[Addr]) Get(sumIdx int64) (ShortSum, error) { - if len(sg) == 0 { - return "", io.EOF - } - addr := sg[0].Addr.Add(btrfsvol.AddrDelta(sumIdx) * CSumBlockSize) + addr := sg.Addr.Add(btrfsvol.AddrDelta(sumIdx) * CSumBlockSize) return sg.SumForAddr(addr) } diff --git a/lib/btrfsprogs/btrfsinspect/scanforextents/scan.go b/lib/btrfsprogs/btrfsinspect/scanforextents/scan.go index ca3036a..9219787 100644 --- a/lib/btrfsprogs/btrfsinspect/scanforextents/scan.go +++ b/lib/btrfsprogs/btrfsinspect/scanforextents/scan.go @@ -23,6 +23,10 @@ func ScanForExtents(ctx context.Context, fs *btrfs.FS, blockgroups map[btrfsvol. bgSums := make(map[btrfsvol.LogicalAddr]SumRunWithGaps[btrfsvol.LogicalAddr]) for i, bgLAddr := range maps.SortedKeys(blockgroups) { blockgroup := blockgroups[bgLAddr] + runs := SumRunWithGaps[btrfsvol.LogicalAddr]{ + Addr: blockgroup.LAddr, + Size: blockgroup.Size, + } for laddr := blockgroup.LAddr; laddr < blockgroup.LAddr.Add(blockgroup.Size); { run, next, ok := sums.RunForLAddr(laddr) if !ok { @@ -34,15 +38,16 @@ func ScanForExtents(ctx context.Context, fs *btrfs.FS, blockgroups map[btrfsvol. blockgroup.Size-laddr.Sub(blockgroup.LAddr), btrfsvol.AddrDelta((len(run.Sums)-off)/run.ChecksumSize)*CSumBlockSize) deltaOff := int(deltaAddr/CSumBlockSize) * run.ChecksumSize - bgSums[blockgroup.LAddr] = append(bgSums[blockgroup.LAddr], SumRun[btrfsvol.LogicalAddr]{ + runs.Runs = append(runs.Runs, SumRun[btrfsvol.LogicalAddr]{ ChecksumSize: run.ChecksumSize, Addr: laddr, Sums: run.Sums[off : off+deltaOff], }) laddr = laddr.Add(deltaAddr) } - dlog.Infof(ctx, "... (%v/%v) blockgroup[laddr=%v] has %v runs", - i+1, len(blockgroups), bgLAddr, len(bgSums[blockgroup.LAddr])) + bgSums[blockgroup.LAddr] = runs + dlog.Infof(ctx, "... (%v/%v) blockgroup[laddr=%v] has %v runs covering %v%%", + i+1, len(blockgroups), bgLAddr, len(runs.Runs), int(runs.PctFull())) } dlog.Info(ctx, "... done pairing") @@ -50,13 +55,12 @@ func ScanForExtents(ctx context.Context, fs *btrfs.FS, blockgroups map[btrfsvol. gaps := ListPhysicalGaps(fs) bgMatches := make(map[btrfsvol.LogicalAddr][]btrfsvol.QualifiedPhysicalAddr) for i, bgLAddr := range maps.SortedKeys(blockgroups) { - bgRuns := bgSums[bgLAddr] - if len(bgRuns) == 0 { + bgRun := bgSums[bgLAddr] + if len(bgRun.Runs) == 0 { dlog.Errorf(ctx, "... (%v/%v) blockgroup[laddr=%v] can't be matched because it has 0 runs", i+1, len(bgSums), bgLAddr) continue } - bgRun := bgRuns[0] if err := WalkGaps(ctx, sums, gaps, func(devID btrfsvol.DeviceID, gap SumRun[btrfsvol.PhysicalAddr]) error { matches, err := diskio.IndexAll[int64, ShortSum](gap, bgRun) -- cgit v1.2.3-2-g168b