[partition] Correctly handle percentage-define partitions

* Use the minSize when the target storage is smaller than the sum of sizes
 * Percentage-defined partitions should be computed after setting hard-defined ones

This fixes issues when 0 byte partitions were created when the disk is too small.
Also fixes an issue with percent-defined partitions being forced to be defined at the end of the disk.
This commit is contained in:
Corentin Noël 2020-09-16 12:46:28 +02:00
parent e84f446c5f
commit 75fd1dd114

View File

@ -164,60 +164,118 @@ PartitionLayout::execute( Device* dev,
const PartitionRole& role ) const PartitionRole& role )
{ {
QList< Partition* > partList; QList< Partition* > partList;
// Map each partition entry to its requested size (0 when calculated later)
QMap< const PartitionLayout::PartitionEntry *, qint64 > partSizeMap;
qint64 minSize, maxSize, end; qint64 minSize, maxSize, end;
qint64 totalSize = lastSector - firstSector + 1; qint64 totalSize = lastSector - firstSector + 1;
qint64 availableSize = totalSize; qint64 availableSize = totalSize;
// TODO: Refine partition sizes to make sure there is room for every partition // Let's check if we have enough space for each partSize
// Use a default (200-500M ?) minimum size for partition without minSize for( const PartitionLayout::PartitionEntry& part : m_partLayout )
foreach ( const PartitionLayout::PartitionEntry& part, m_partLayout )
{ {
Partition* currentPartition = nullptr;
qint64 size = -1; qint64 size = -1;
// Calculate partition size // Calculate partition size
if ( part.partSize.isValid() ) if ( part.partSize.isValid() )
{
// We need to ignore the percent-defined
if ( part.partSize.unit() != CalamaresUtils::Partition::SizeUnit::Percent)
{ {
size = part.partSize.toSectors( totalSize, dev->logicalSize() ); size = part.partSize.toSectors( totalSize, dev->logicalSize() );
} }
else else
{
if ( part.partMinSize.isValid() )
{
size = part.partMinSize.toSectors( totalSize, dev->logicalSize() );
}
else
{
size = 0;
}
}
}
else
{ {
cWarning() << "Partition" << part.partMountPoint << "size (" << size << "sectors) is invalid, skipping..."; cWarning() << "Partition" << part.partMountPoint << "size (" << size << "sectors) is invalid, skipping...";
continue; continue;
} }
partSizeMap.insert (&part, size);
availableSize -= size;
}
// Use partMinSize and see if we can do better afterward.
if (availableSize < 0)
{
availableSize = totalSize;
for( const PartitionLayout::PartitionEntry& part : m_partLayout )
{
qint64 size;
if ( part.partMinSize.isValid() ) if ( part.partMinSize.isValid() )
{ {
minSize = part.partMinSize.toSectors( totalSize, dev->logicalSize() ); size = part.partMinSize.toSectors( totalSize, dev->logicalSize() );
}
else if ( part.partSize.isValid() )
{
if ( part.partSize.unit() != CalamaresUtils::Partition::SizeUnit::Percent)
{
size = part.partSize.toSectors( totalSize, dev->logicalSize() );
} }
else else
{ {
minSize = 0; size = 0;
} }
if ( part.partMaxSize.isValid() )
{
maxSize = part.partMaxSize.toSectors( totalSize, dev->logicalSize() );
} }
else else
{ {
maxSize = availableSize; size = 0;
} }
// Make sure we never go under minSize once converted to sectors partSizeMap.insert (&part, size);
if ( maxSize < minSize ) availableSize -= size;
}
}
// Assign size for percentage-defined partitions
for( const PartitionLayout::PartitionEntry& part : m_partLayout )
{ {
cWarning() << "Partition" << part.partMountPoint << "max size (" << maxSize << "sectors) is < min size (" if ( part.partSize.unit() == CalamaresUtils::Partition::SizeUnit::Percent)
<< minSize << "sectors), using min size"; {
maxSize = minSize; qint64 size = partSizeMap.value (&part);
} size = part.partSize.toSectors( availableSize + size, dev->logicalSize() );
partSizeMap.insert (&part, size);
// Adjust partition size based on user-defined boundaries and available space if ( part.partMinSize.isValid() )
if ( size < minSize ) {
qint64 minSize = part.partMinSize.toSectors( totalSize, dev->logicalSize() );
if (minSize > size)
{ {
size = minSize; size = minSize;
} }
}
if ( part.partMaxSize.isValid() )
{
qint64 maxSize = part.partMaxSize.toSectors( totalSize, dev->logicalSize() );
if (maxSize < size)
{
size = maxSize;
}
}
}
}
availableSize = totalSize;
// TODO: Refine partition sizes to make sure there is room for every partition
// Use a default (200-500M ?) minimum size for partition without minSize
for( const PartitionLayout::PartitionEntry& part : m_partLayout )
{
qint64 size = partSizeMap.value (&part);
Partition* currentPartition = nullptr;
// Adjust partition size based on user-defined boundaries and available space
if ( size > maxSize ) if ( size > maxSize )
{ {
size = maxSize; size = maxSize;