Avoid erasing the same range multiple times (!123)

When the size of the partition being cleared is an exact multiple of
MiBs, likely given that GParted aligns partitions to whole MiBs by
default, then the same range will be zeroed 4 times in a row.  Example
operation details from clearing a partition look like this:

    Format /dev/sdb1 as cleared
    + calibrate /dev/sdb1
        path: /dev/sdb1 (partition)
        start: 2048
        end: 2099199
        size: 2097152 (1.00 GiB)
    + clear old file system signatures in /dev/sdb1
        write 512.00 KiB of zeros at byte offset 0
        write 4.00 KiB of zeros at byte offset 67108864
        write 512.00 B of zeros at byte offset 1072161280
>>      write 4.00 KiB of zeros at byte offset 1072693248
>>      write 4.00 KiB of zeros at byte offset 1072693248
>>      write 4.00 KiB of zeros at byte offset 1072693248
>>      write 4.00 KiB of zeros at byte offset 1072693248
        write 512.00 KiB of zeros at byte offset 1073217536
    + set partition type on /dev/sdb1

This is because the bcachefs backup super block is located at -1 MiB
from the end of the device, rounded down by the bcachefs bucket size.
The bucket size can be any of 128 KiB, 256 KiB, 512 KiB or 1 MiB,
depending on the size of the bcachefs file system.  So when the
partition size is an exact multiple of MiBs all 4 possible rounding
sizes result in the same offset.

Avoid writing the same range of zeros multiple times by skipping a range
if it is identical to the previous range.

Closes !123 - Add support for bcachefs, single device file systems only
This commit is contained in:
Mike Fleetwood 2024-03-23 08:01:20 +00:00
parent 76b27b9f7a
commit f027809e73

View file

@ -3831,6 +3831,8 @@ bool GParted_Core::erase_filesystem_signatures( const Partition & partition, Ope
{ -1LL * MEBIBYTE, 1LL * MEBIBYTE, 4LL * KIBIBYTE }, // Bcachefs backup super block
{ -512LL * KIBIBYTE, 256LL * KIBIBYTE, 768LL * KIBIBYTE } // Super blocks at end
} ;
Byte_Value prev_byte_offset = -1;
Byte_Value prev_byte_len = -1;
for ( unsigned int i = 0 ; overall_success && i < sizeof( ranges ) / sizeof( ranges[0] ) ; i ++ )
{
//Rounding is performed in multiples of the sector size because writes are in whole sectors.
@ -3879,6 +3881,10 @@ bool GParted_Core::erase_filesystem_signatures( const Partition & partition, Ope
byte_len = partition .get_byte_length() - byte_offset ;
}
if (byte_offset == prev_byte_offset && byte_len == prev_byte_len)
// Byte range identical to previous. Skip.
continue;
OperationDetail & od = operationdetail .get_last_child() ;
Byte_Value written = 0LL ;
bool zero_success = false ;
@ -3904,6 +3910,10 @@ bool GParted_Core::erase_filesystem_signatures( const Partition & partition, Ope
written += amount ;
}
// Save byte range for detection of following identical range.
prev_byte_offset = byte_offset;
prev_byte_len = byte_len;
od.get_last_child().set_success_and_capture_errors( zero_success );
}
overall_success &= zero_success ;