]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
repart: fix free area calculations for unaligned partitions
authorLennart Poettering <lennart@poettering.net>
Tue, 9 Nov 2021 15:31:48 +0000 (16:31 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 9 Nov 2021 15:31:48 +0000 (16:31 +0100)
To properly detect how much space we have to distribute we need to take
into account that both the partition offset and the partition size
aren't aligned.

src/partition/repart.c

index 3ff97520056ad665c9d84eac78ee3b6afed729ab..5e6e88df94e198b63184ddda0d7dfde49b57285c 100644 (file)
@@ -505,18 +505,21 @@ static uint64_t free_area_available_for_new_partitions(const FreeArea *a) {
 
         avail = free_area_available(a);
         if (a->after) {
-                uint64_t need, space;
+                uint64_t need, space_end, new_end;
 
                 need = partition_min_size_with_padding(a->after);
 
                 assert(a->after->offset != UINT64_MAX);
                 assert(a->after->current_size != UINT64_MAX);
 
-                space = round_up_size(a->after->offset + a->after->current_size, 4096) - a->after->offset + avail;
-                if (need >= space)
-                        return 0;
+                /* Calculate where the free area ends, based on the offset of the partition preceding it */
+                space_end = round_up_size(a->after->offset + a->after->current_size, 4096) + avail;
+
+                /* Calculate where the partition would end when we give it as much as it needs */
+                new_end = round_up_size(a->after->offset + need, 4096);
 
-                return space - need;
+                /* Calculate saturated difference of the two: that's how much we have free for other partitions */
+                return LESS_BY(space_end, new_end);
         }
 
         return avail;