summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdrian Vovk <adrianvovk@gmail.com>2024-09-05 02:19:27 +0200
committerAdrian Vovk <adrianvovk@gmail.com>2024-09-17 20:06:49 +0200
commit78e9059208c0a161ee6dc95c122ca7810b49a033 (patch)
treeafa40c34913220eade866c65adbfb7444fb3f291 /src
parentstrv: Fixup STRV_FOREACH_PAIR macro (diff)
downloadsystemd-78e9059208c0a161ee6dc95c122ca7810b49a033.tar.xz
systemd-78e9059208c0a161ee6dc95c122ca7810b49a033.zip
repart: Consider existing partitions when placing
Fixes an oversight in `context_allocate_partitions` that makes it succeed in cases where it should fail. Essentially, there was nothing actually enforcing SizeMinBytes= and PaddingMinBytes= for partitions that exist, only for new partitions. This behavior is inconsistent with the docs, which state that existing partitions will be grown to at least the specified minimum size, and that "If the backing device does not provide enough space to fulfill the constraints placing the partition will fail".
Diffstat (limited to 'src')
-rw-r--r--src/partition/repart.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/partition/repart.c b/src/partition/repart.c
index b430d2d463..e1608bd64d 100644
--- a/src/partition/repart.c
+++ b/src/partition/repart.c
@@ -977,14 +977,22 @@ static bool context_allocate_partitions(Context *context, uint64_t *ret_largest_
uint64_t required;
FreeArea *a = NULL;
- /* Skip partitions we already dropped or that already exist */
- if (p->dropped || PARTITION_EXISTS(p))
+ if (p->dropped || PARTITION_IS_FOREIGN(p))
continue;
/* How much do we need to fit? */
required = partition_min_size_with_padding(context, p);
assert(required % context->grain_size == 0);
+ /* For existing partitions, we should verify that they'll actually fit */
+ if (PARTITION_EXISTS(p)) {
+ if (p->current_size + p->current_padding < required)
+ return false; /* 😢 We won't be able to grow to the required min size! */
+
+ continue;
+ }
+
+ /* For new partitions, see if there's a free area big enough */
for (size_t i = 0; i < context->n_free_areas; i++) {
a = context->free_areas[i];