diff options
Diffstat (limited to 'lib/btrfsprogs/btrfsinspect')
-rw-r--r-- | lib/btrfsprogs/btrfsinspect/csums.go (renamed from lib/btrfsprogs/btrfsinspect/scanforextents/csums.go) | 4 | ||||
-rw-r--r-- | lib/btrfsprogs/btrfsinspect/rebuildmappings/blockgroups.go (renamed from lib/btrfsprogs/btrfsinspect/scanforextents/blockgroups.go) | 2 | ||||
-rw-r--r-- | lib/btrfsprogs/btrfsinspect/rebuildmappings/gaps.go (renamed from lib/btrfsprogs/btrfsinspect/scanforextents/gaps.go) | 9 | ||||
-rw-r--r-- | lib/btrfsprogs/btrfsinspect/rebuildmappings/scan.go (renamed from lib/btrfsprogs/btrfsinspect/scanforextents/scan.go) | 19 | ||||
-rw-r--r-- | lib/btrfsprogs/btrfsinspect/scan.go | 57 | ||||
-rw-r--r-- | lib/btrfsprogs/btrfsinspect/scandevices.go (renamed from lib/btrfsprogs/btrfsinspect/recoverchunks.go) | 3 | ||||
-rw-r--r-- | lib/btrfsprogs/btrfsinspect/scanforextents/csums_raw.go | 66 |
7 files changed, 76 insertions, 84 deletions
diff --git a/lib/btrfsprogs/btrfsinspect/scanforextents/csums.go b/lib/btrfsprogs/btrfsinspect/csums.go index 0fb4818..a062a77 100644 --- a/lib/btrfsprogs/btrfsinspect/scanforextents/csums.go +++ b/lib/btrfsprogs/btrfsinspect/csums.go @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -package scanforextents +package btrfsinspect import ( "context" @@ -285,7 +285,7 @@ func SumEverything(ctx context.Context, fs *btrfs.FS) (AllSums, error) { return err } progress(i) - sum, err := ChecksumPhysical(dev, alg, btrfsvol.PhysicalAddr(i*btrfsitem.CSumBlockSize)) + sum, err := btrfsutil.ChecksumPhysical(dev, alg, btrfsvol.PhysicalAddr(i*btrfsitem.CSumBlockSize)) if err != nil { return err } diff --git a/lib/btrfsprogs/btrfsinspect/scanforextents/blockgroups.go b/lib/btrfsprogs/btrfsinspect/rebuildmappings/blockgroups.go index d8e8844..15df6da 100644 --- a/lib/btrfsprogs/btrfsinspect/scanforextents/blockgroups.go +++ b/lib/btrfsprogs/btrfsinspect/rebuildmappings/blockgroups.go @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -package scanforextents +package rebuildmappings import ( "encoding/json" diff --git a/lib/btrfsprogs/btrfsinspect/scanforextents/gaps.go b/lib/btrfsprogs/btrfsinspect/rebuildmappings/gaps.go index be6ee06..f5fb27a 100644 --- a/lib/btrfsprogs/btrfsinspect/scanforextents/gaps.go +++ b/lib/btrfsprogs/btrfsinspect/rebuildmappings/gaps.go @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -package scanforextents +package rebuildmappings import ( "context" @@ -13,6 +13,7 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/btrfs" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsitem" "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" ) @@ -55,8 +56,8 @@ func roundUp[T constraints.Integer](x, multiple T) T { } func WalkGaps(ctx context.Context, - sums AllSums, gaps map[btrfsvol.DeviceID][]PhysicalGap, - fn func(btrfsvol.DeviceID, SumRun[btrfsvol.PhysicalAddr]) error, + sums btrfsinspect.AllSums, gaps map[btrfsvol.DeviceID][]PhysicalGap, + fn func(btrfsvol.DeviceID, btrfsinspect.SumRun[btrfsvol.PhysicalAddr]) error, ) error { for _, devID := range maps.SortedKeys(gaps) { for _, gap := range gaps[devID] { @@ -66,7 +67,7 @@ func WalkGaps(ctx context.Context, begAddr := roundUp(gap.Beg, btrfsitem.CSumBlockSize) begOff := int(begAddr/btrfsitem.CSumBlockSize) * sums.Physical[devID].ChecksumSize endOff := int(gap.End/btrfsitem.CSumBlockSize) * sums.Physical[devID].ChecksumSize - if err := fn(devID, SumRun[btrfsvol.PhysicalAddr]{ + if err := fn(devID, btrfsinspect.SumRun[btrfsvol.PhysicalAddr]{ ChecksumSize: sums.Physical[devID].ChecksumSize, Addr: begAddr, Sums: sums.Physical[devID].Sums[begOff:endOff], diff --git a/lib/btrfsprogs/btrfsinspect/scanforextents/scan.go b/lib/btrfsprogs/btrfsinspect/rebuildmappings/scan.go index e980e9c..83c4a31 100644 --- a/lib/btrfsprogs/btrfsinspect/scanforextents/scan.go +++ b/lib/btrfsprogs/btrfsinspect/rebuildmappings/scan.go @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -package scanforextents +package rebuildmappings import ( "context" @@ -13,18 +13,19 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/btrfs" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsitem" "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/containers" "git.lukeshu.com/btrfs-progs-ng/lib/diskio" "git.lukeshu.com/btrfs-progs-ng/lib/maps" "git.lukeshu.com/btrfs-progs-ng/lib/slices" ) -func ScanForExtents(ctx context.Context, fs *btrfs.FS, blockgroups map[btrfsvol.LogicalAddr]BlockGroup, sums AllSums) error { +func ScanForExtents(ctx context.Context, fs *btrfs.FS, blockgroups map[btrfsvol.LogicalAddr]BlockGroup, sums btrfsinspect.AllSums) error { dlog.Info(ctx, "Pairing up blockgroups and sums...") - bgSums := make(map[btrfsvol.LogicalAddr]SumRunWithGaps[btrfsvol.LogicalAddr]) + bgSums := make(map[btrfsvol.LogicalAddr]btrfsinspect.SumRunWithGaps[btrfsvol.LogicalAddr]) for i, bgLAddr := range maps.SortedKeys(blockgroups) { blockgroup := blockgroups[bgLAddr] - runs := SumRunWithGaps[btrfsvol.LogicalAddr]{ + runs := btrfsinspect.SumRunWithGaps[btrfsvol.LogicalAddr]{ Addr: blockgroup.LAddr, Size: blockgroup.Size, } @@ -39,7 +40,7 @@ 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)*btrfsitem.CSumBlockSize) deltaOff := int(deltaAddr/btrfsitem.CSumBlockSize) * run.ChecksumSize - runs.Runs = append(runs.Runs, SumRun[btrfsvol.LogicalAddr]{ + runs.Runs = append(runs.Runs, btrfsinspect.SumRun[btrfsvol.LogicalAddr]{ ChecksumSize: run.ChecksumSize, Addr: laddr, Sums: run.Sums[off : off+deltaOff], @@ -63,8 +64,8 @@ func ScanForExtents(ctx context.Context, fs *btrfs.FS, blockgroups map[btrfsvol. continue } - if err := WalkGaps(ctx, sums, gaps, func(devID btrfsvol.DeviceID, gap SumRun[btrfsvol.PhysicalAddr]) error { - matches, err := diskio.IndexAll[int64, ShortSum](gap, bgRun) + if err := WalkGaps(ctx, sums, gaps, func(devID btrfsvol.DeviceID, gap btrfsinspect.SumRun[btrfsvol.PhysicalAddr]) error { + matches, err := diskio.IndexAll[int64, btrfsinspect.ShortSum](gap, bgRun) if err != nil { return err } @@ -112,9 +113,9 @@ func ScanForExtents(ctx context.Context, fs *btrfs.FS, blockgroups map[btrfsvol. dlog.Info(ctx, "... done applying") dlog.Info(ctx, "Reverse-indexing remaining unmapped logical sums...") - sum2laddrs := make(map[ShortSum][]btrfsvol.LogicalAddr) + sum2laddrs := make(map[btrfsinspect.ShortSum][]btrfsvol.LogicalAddr) var numUnmappedBlocks int64 - if err := sums.WalkLogical(ctx, func(laddr btrfsvol.LogicalAddr, sum ShortSum) error { + if err := sums.WalkLogical(ctx, func(laddr btrfsvol.LogicalAddr, sum btrfsinspect.ShortSum) error { var dat [btrfsitem.CSumBlockSize]byte if _, err := fs.ReadAt(dat[:], laddr); err != nil { if errors.Is(err, btrfsvol.ErrCouldNotMap) { diff --git a/lib/btrfsprogs/btrfsinspect/scan.go b/lib/btrfsprogs/btrfsinspect/scan.go new file mode 100644 index 0000000..ef1079f --- /dev/null +++ b/lib/btrfsprogs/btrfsinspect/scan.go @@ -0,0 +1,57 @@ +// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com> +// +// SPDX-License-Identifier: GPL-2.0-or-later + +package btrfsinspect + +import ( + "context" + "errors" + "fmt" + + "git.lukeshu.com/btrfs-progs-ng/lib/btrfs" + "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol" + "git.lukeshu.com/btrfs-progs-ng/lib/diskio" + "git.lukeshu.com/btrfs-progs-ng/lib/slices" +) + +// ScanForNodes mimics btrfs-progs +// cmds/rescue-chunk-recover.c:scan_one_device(), except rather than +// doing something itself when it finds a node, it simply calls a +// callback function. +func ScanForNodes(ctx context.Context, dev *btrfs.Device, sb btrfs.Superblock, fn func(*diskio.Ref[btrfsvol.PhysicalAddr, btrfs.Node], error), prog func(btrfsvol.PhysicalAddr)) error { + devSize := dev.Size() + + if sb.NodeSize < sb.SectorSize { + return fmt.Errorf("node_size(%v) < sector_size(%v)", + sb.NodeSize, sb.SectorSize) + } + + for pos := btrfsvol.PhysicalAddr(0); pos+btrfsvol.PhysicalAddr(sb.NodeSize) < devSize; pos += btrfsvol.PhysicalAddr(sb.SectorSize) { + if ctx.Err() != nil { + return ctx.Err() + } + if slices.Contains(pos, btrfs.SuperblockAddrs) { + //fmt.Printf("sector@%v is a superblock\n", pos) + continue + } + + if prog != nil { + prog(pos) + } + + nodeRef, err := btrfs.ReadNode[btrfsvol.PhysicalAddr](dev, sb, pos, nil) + if err != nil && errors.Is(err, btrfs.ErrNotANode) { + continue + } + fn(nodeRef, err) + + pos += btrfsvol.PhysicalAddr(sb.NodeSize) - btrfsvol.PhysicalAddr(sb.SectorSize) + } + + if prog != nil { + prog(devSize) + } + + return nil +} diff --git a/lib/btrfsprogs/btrfsinspect/recoverchunks.go b/lib/btrfsprogs/btrfsinspect/scandevices.go index b3abf75..13c5d60 100644 --- a/lib/btrfsprogs/btrfsinspect/recoverchunks.go +++ b/lib/btrfsprogs/btrfsinspect/scandevices.go @@ -13,7 +13,6 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/btrfs" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsitem" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol" - "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsutil" "git.lukeshu.com/btrfs-progs-ng/lib/containers" "git.lukeshu.com/btrfs-progs-ng/lib/diskio" "git.lukeshu.com/btrfs-progs-ng/lib/maps" @@ -159,7 +158,7 @@ func ScanOneDevice(ctx context.Context, dev *btrfs.Device, superblock btrfs.Supe devSize := dev.Size() lastProgress := -1 - err := btrfsutil.ScanForNodes(ctx, dev, superblock, func(nodeRef *diskio.Ref[btrfsvol.PhysicalAddr, btrfs.Node], err error) { + err := ScanForNodes(ctx, dev, superblock, func(nodeRef *diskio.Ref[btrfsvol.PhysicalAddr, btrfs.Node], err error) { if err != nil { dlog.Infof(ctx, "... dev[%q] error: %v", dev.Name(), err) return diff --git a/lib/btrfsprogs/btrfsinspect/scanforextents/csums_raw.go b/lib/btrfsprogs/btrfsinspect/scanforextents/csums_raw.go deleted file mode 100644 index eae1c4d..0000000 --- a/lib/btrfsprogs/btrfsinspect/scanforextents/csums_raw.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com> -// -// SPDX-License-Identifier: GPL-2.0-or-later - -package scanforextents - -import ( - "fmt" - - "git.lukeshu.com/btrfs-progs-ng/lib/btrfs" - "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsitem" - "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfssum" - "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol" -) - -func ChecksumLogical(fs btrfs.Trees, alg btrfssum.CSumType, laddr btrfsvol.LogicalAddr) (btrfssum.CSum, error) { - var dat [btrfsitem.CSumBlockSize]byte - if _, err := fs.ReadAt(dat[:], laddr); err != nil { - return btrfssum.CSum{}, err - } - return alg.Sum(dat[:]) -} - -func ChecksumPhysical(dev *btrfs.Device, alg btrfssum.CSumType, paddr btrfsvol.PhysicalAddr) (btrfssum.CSum, error) { - var dat [btrfsitem.CSumBlockSize]byte - if _, err := dev.ReadAt(dat[:], paddr); err != nil { - return btrfssum.CSum{}, err - } - return alg.Sum(dat[:]) -} - -func ChecksumQualifiedPhysical(fs *btrfs.FS, alg btrfssum.CSumType, paddr btrfsvol.QualifiedPhysicalAddr) (btrfssum.CSum, error) { - dev := fs.LV.PhysicalVolumes()[paddr.Dev] - if dev == nil { - return btrfssum.CSum{}, fmt.Errorf("no such device_id=%v", paddr.Dev) - } - return ChecksumPhysical(dev, alg, paddr.Addr) -} - -func LookupCSum(fs btrfs.Trees, alg btrfssum.CSumType, laddr btrfsvol.LogicalAddr) (map[btrfsvol.LogicalAddr]btrfssum.CSum, error) { - item, err := fs.TreeSearch(btrfs.CSUM_TREE_OBJECTID, func(key btrfs.Key, size uint32) int { - itemBeg := btrfsvol.LogicalAddr(key.ObjectID) - numSums := int64(size) / int64(alg.Size()) - itemEnd := itemBeg + btrfsvol.LogicalAddr(numSums*btrfsitem.CSumBlockSize) - switch { - case itemEnd <= laddr: - return 1 - case laddr < itemBeg: - return -1 - default: - return 0 - } - }) - if err != nil { - return nil, err - } - body, ok := item.Body.(btrfsitem.ExtentCSum) - if !ok { - return nil, fmt.Errorf("item body is %T not ExtentCSum", item.Body) - } - ret := make(map[btrfsvol.LogicalAddr]btrfssum.CSum, len(body.Sums)) - for i, sum := range body.Sums { - ret[btrfsvol.LogicalAddr(item.Key.ObjectID)+(btrfsvol.LogicalAddr(i)*btrfsitem.CSumBlockSize)] = sum - } - return ret, nil -} |