diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2023-02-05 10:21:33 -0700 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2023-02-12 02:43:16 -0700 |
commit | b608e4cf9c9e6e5bf5a333e8d78b2800ffcb0c91 (patch) | |
tree | 2cebbe4d02dfb1b993f97977a4eb3aec278336c9 /lib | |
parent | a20926015f050f34b8a4dff17f80af6c6224e22c (diff) |
btrfsvol: Add a sanity check
Diffstat (limited to 'lib')
-rw-r--r-- | lib/btrfs/btrfsvol/blockgroupflags.go | 5 | ||||
-rw-r--r-- | lib/btrfs/btrfsvol/lvm.go | 26 |
2 files changed, 31 insertions, 0 deletions
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 } |