summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/btrfs-fsck/pass1.go53
-rw-r--r--pkg/btrfs/btrfsvol/lvm.go6
2 files changed, 40 insertions, 19 deletions
diff --git a/cmd/btrfs-fsck/pass1.go b/cmd/btrfs-fsck/pass1.go
index 32d9456..a83697f 100644
--- a/cmd/btrfs-fsck/pass1.go
+++ b/cmd/btrfs-fsck/pass1.go
@@ -90,30 +90,13 @@ func (found pass1ScanOneDevResult) AddToLV(fs *btrfs.FS, dev *btrfs.Device) {
printProgress := func() {
pct := int(100 * float64(done) / float64(total))
if pct != lastProgress || done == total {
- fmt.Printf("Pass 1: ... added %v%% of the mappings (%v/%v)\n",
- pct, done, total)
+ fmt.Printf("Pass 1: ... added %v%% of the mappings (%v/%v=>%v)\n",
+ pct, done, total, len(fs.LV.Mappings()))
lastProgress = pct
}
}
printProgress()
- for laddr, paddrs := range found.FoundNodes {
- for _, paddr := range paddrs {
- if err := fs.LV.AddMapping(btrfsvol.Mapping{
- LAddr: laddr,
- PAddr: btrfsvol.QualifiedPhysicalAddr{
- Dev: sb.Data.DevItem.DevID,
- Addr: paddr,
- },
- Size: btrfsvol.AddrDelta(sb.Data.NodeSize),
- Flags: nil,
- }); err != nil {
- fmt.Printf("Pass 1: ... error: adding node ident: %v\n", err)
- }
- done++
- printProgress()
- }
- }
for _, chunk := range found.FoundChunks {
for _, mapping := range chunk.Chunk.Mappings(chunk.Key) {
if err := fs.LV.AddMapping(mapping); err != nil {
@@ -123,6 +106,7 @@ func (found pass1ScanOneDevResult) AddToLV(fs *btrfs.FS, dev *btrfs.Device) {
printProgress()
}
}
+
for _, ext := range found.FoundDevExtents {
if err := fs.LV.AddMapping(ext.DevExt.Mapping(ext.Key)); err != nil {
fmt.Printf("Pass 1: ... error: adding devext: %v\n", err)
@@ -130,6 +114,37 @@ func (found pass1ScanOneDevResult) AddToLV(fs *btrfs.FS, dev *btrfs.Device) {
done++
printProgress()
}
+
+ // Do the nodes last to avoid bloating the mappings table too
+ // much.
+ //
+ // Sort them so that progress numbers are predictable.
+ laddrs := make([]btrfsvol.LogicalAddr, 0, len(found.FoundNodes))
+ for laddr := range found.FoundNodes {
+ laddrs = append(laddrs, laddr)
+ }
+ sort.Slice(laddrs, func(i, j int) bool {
+ // And sort them in reverse order to keep insertions
+ // fast.
+ return laddrs[i] > laddrs[j]
+ })
+ for _, laddr := range laddrs {
+ for _, paddr := range found.FoundNodes[laddr] {
+ if err := fs.LV.AddMapping(btrfsvol.Mapping{
+ LAddr: laddr,
+ PAddr: btrfsvol.QualifiedPhysicalAddr{
+ Dev: sb.Data.DevItem.DevID,
+ Addr: paddr,
+ },
+ Size: btrfsvol.AddrDelta(sb.Data.NodeSize),
+ Flags: nil,
+ }); err != nil {
+ fmt.Printf("Pass 1: ... error: adding node ident: %v\n", err)
+ }
+ done++
+ printProgress()
+ }
+ }
}
func pass1ScanOneDev(dev *btrfs.Device, superblock btrfs.Superblock) (pass1ScanOneDevResult, error) {
diff --git a/pkg/btrfs/btrfsvol/lvm.go b/pkg/btrfs/btrfsvol/lvm.go
index a145f3e..d11b2f0 100644
--- a/pkg/btrfs/btrfsvol/lvm.go
+++ b/pkg/btrfs/btrfsvol/lvm.go
@@ -122,6 +122,12 @@ func (lv *LogicalVolume[PhysicalVolume]) AddMapping(m Mapping) error {
return fmt.Errorf("(%p).AddMapping: %w", lv, err)
}
+ // optimize
+ if len(logicalOverlaps) == 1 && reflect.DeepEqual(newChunk, logicalOverlaps[0]) &&
+ len(physicalOverlaps) == 1 && reflect.DeepEqual(newExt, physicalOverlaps[0]) {
+ return nil
+ }
+
// logical2physical
for _, chunk := range logicalOverlaps {
lv.logical2physical = util.RemoveAllFromSliceFunc(lv.logical2physical, func(otherChunk chunkMapping) bool {