From b608e4cf9c9e6e5bf5a333e8d78b2800ffcb0c91 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 5 Feb 2023 10:21:33 -0700 Subject: btrfsvol: Add a sanity check --- lib/btrfs/btrfsvol/blockgroupflags.go | 5 +++++ lib/btrfs/btrfsvol/lvm.go | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) (limited to 'lib/btrfs/btrfsvol') diff --git a/lib/btrfs/btrfsvol/blockgroupflags.go b/lib/btrfs/btrfsvol/blockgroupflags.go index 4ca5544..0125664 100644 --- a/lib/btrfs/btrfsvol/blockgroupflags.go +++ b/lib/btrfs/btrfsvol/blockgroupflags.go @@ -23,6 +23,11 @@ const ( BLOCK_GROUP_RAID1C3 BLOCK_GROUP_RAID1C4 + // BLOCK_GROUP_RAID_MASK is the set of bits that mean that + // mean the logical:physical relationship is a one:many + // relationship rather than a one:one relationship. + // + // Notably, this does not include BLOCK_GROUP_RAID0. BLOCK_GROUP_RAID_MASK = (BLOCK_GROUP_RAID1 | BLOCK_GROUP_DUP | BLOCK_GROUP_RAID10 | BLOCK_GROUP_RAID5 | BLOCK_GROUP_RAID6 | BLOCK_GROUP_RAID1C3 | BLOCK_GROUP_RAID1C4) ) diff --git a/lib/btrfs/btrfsvol/lvm.go b/lib/btrfs/btrfsvol/lvm.go index b83e9cd..59ca609 100644 --- a/lib/btrfs/btrfsvol/lvm.go +++ b/lib/btrfs/btrfsvol/lvm.go @@ -144,6 +144,10 @@ func (lv *LogicalVolume[PhysicalVolume]) addMapping(m Mapping, dryRun bool) erro Flags: m.Flags, } logicalOverlaps := lv.logical2physical.SearchRange(newChunk.compareRange) + numOverlappingStripes := 0 + for _, chunk := range logicalOverlaps { + numOverlappingStripes += len(chunk.PAddrs) + } var err error newChunk, err = newChunk.union(logicalOverlaps...) if err != nil { @@ -164,6 +168,28 @@ func (lv *LogicalVolume[PhysicalVolume]) addMapping(m Mapping, dryRun bool) erro return fmt.Errorf("(%p).AddMapping: %w", lv, err) } + if newChunk.Flags != newExt.Flags { + // If these don't match up, it's a bug in this code. + panic(fmt.Errorf("should not happen: newChunk.Flags:%+v != newExt.Flags:%+v", + newChunk.Flags, newExt.Flags)) + } + switch { + case len(physicalOverlaps) == numOverlappingStripes: + // normal case + case len(physicalOverlaps) < numOverlappingStripes: + // .Flags = DUP or RAID{X} + if newChunk.Flags.OK && newChunk.Flags.Val&BLOCK_GROUP_RAID_MASK == 0 { + return fmt.Errorf("multiple stripes but flags=%v does not allow multiple stripes", + newChunk.Flags.Val) + } + case len(physicalOverlaps) > numOverlappingStripes: + // This should not happen because calling .AddMapping + // should update the two in lockstep; if these don't + // match up, it's a bug in this code. + panic(fmt.Errorf("should not happen: len(physicalOverlaps):%d != numOverlappingStripes:%d", + len(physicalOverlaps), numOverlappingStripes)) + } + if dryRun { return nil } -- cgit v1.2.3-2-g168b