diff --git a/pkg/disk/btrfs.go b/pkg/disk/btrfs.go index 8175ae4df9..329ebaca89 100644 --- a/pkg/disk/btrfs.go +++ b/pkg/disk/btrfs.go @@ -96,6 +96,20 @@ func (b *Btrfs) MetadataSize() uint64 { return 0 } +func (b *Btrfs) minSize(size uint64) uint64 { + var subvolsum uint64 + for _, sv := range b.Subvolumes { + subvolsum += sv.Size + } + minSize := subvolsum + b.MetadataSize() + + if minSize > size { + size = minSize + } + + return b.AlignUp(size) +} + type BtrfsSubvolume struct { Name string Size uint64 diff --git a/pkg/disk/disk.go b/pkg/disk/disk.go index f2ebc6a6f0..ab389cee97 100644 --- a/pkg/disk/disk.go +++ b/pkg/disk/disk.go @@ -138,6 +138,16 @@ type VolumeContainer interface { // bytes), i.e. the storage space that needs to be reserved for // the container itself, in contrast to the data it contains. MetadataSize() uint64 + + // minSize returns the size for the VolumeContainer that is either the + // provided desired size value or the sum of all children if that is + // larger. It will also add any space required for metadata. The returned + // value should, at minimum, be large enough to fit all the children, their + // metadata, and the VolumeContainer's metadata. In other words, the + // VolumeContainer's size, or its parent size, will be able to hold the + // VolumeContainer if it is created with the exact size returned by the + // function. + minSize(size uint64) uint64 } // FSSpec for a filesystem (UUID and Label); the first field of fstab(5) diff --git a/pkg/disk/luks.go b/pkg/disk/luks.go index 41e7b8594a..6a271b82c8 100644 --- a/pkg/disk/luks.go +++ b/pkg/disk/luks.go @@ -109,3 +109,16 @@ func (lc *LUKSContainer) MetadataSize() uint64 { // 16 MiB is the default size for the LUKS2 header return 16 * common.MiB } + +func (lc *LUKSContainer) minSize(size uint64) uint64 { + // since a LUKS container can contain pretty much any payload, but we only + // care about the ones that have a size, or contain children with sizes + minSize := lc.MetadataSize() + switch payload := lc.Payload.(type) { + case VolumeContainer: + minSize += payload.minSize(size) + case Sizeable: + minSize += payload.GetSize() + } + return minSize +} diff --git a/pkg/disk/lvm.go b/pkg/disk/lvm.go index ccd203a4e2..6d204d29cc 100644 --- a/pkg/disk/lvm.go +++ b/pkg/disk/lvm.go @@ -150,6 +150,20 @@ func (vg *LVMVolumeGroup) MetadataSize() uint64 { return 1 * common.MiB } +func (vg *LVMVolumeGroup) minSize(size uint64) uint64 { + var lvsum uint64 + for _, lv := range vg.LogicalVolumes { + lvsum += lv.Size + } + minSize := lvsum + vg.MetadataSize() + + if minSize > size { + size = minSize + } + + return vg.AlignUp(size) +} + type LVMLogicalVolume struct { Name string Size uint64