diff options
-rw-r--r-- | cmd/btrfs-fsck/pass1.go | 53 | ||||
-rw-r--r-- | pkg/btrfs/btrfsvol/lvm.go | 6 |
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 { |