fs_mgr: Change scratch margin to 3 X logical_block_size.
Found a device with a 3/4MB erase block, give a wider margin so that
flashing a single partition is unlikely to be blocked by scratch.
Add documentation to tell developers to flashall to clear scratch.
Test: adb-remount-test.sh
Bug: 109821005
Change-Id: Ic219283f4c42e457b98991bcd1752253e182eff3
diff --git a/fs_mgr/README.overlayfs.md b/fs_mgr/README.overlayfs.md
index d715d7b..2d42d6c 100644
--- a/fs_mgr/README.overlayfs.md
+++ b/fs_mgr/README.overlayfs.md
@@ -89,4 +89,9 @@
if higher than 4.6.
- *adb enable-verity* will free up overlayfs and as a bonus the
device will be reverted pristine to before any content was updated.
+- If dynamic partitions runs out of space, resizing a logical
+ partition larger may fail because of the scratch partition.
+ If this happens, either fastboot flashall or adb enable-verity can
+ be used to clear scratch storage to permit the flash.
+ Then reinstate the overrides and continue.
- File bugs or submit fixes for review.
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 20652ad..57e984d 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -675,14 +675,26 @@
}
changed = true;
}
- // Take half of free space, minimum 512MB or free space - 256KB margin.
+ // Take half of free space, minimum 512MB or maximum free - margin.
static constexpr auto kMinimumSize = uint64_t(512 * 1024 * 1024);
- static constexpr auto kMarginSize = uint64_t(256 * 1024);
if (partition->size() < kMinimumSize) {
auto partition_size =
builder->AllocatableSpace() - builder->UsedSpace() + partition->size();
if ((partition_size > kMinimumSize) || !partition->size()) {
- partition_size = std::max(std::min(kMinimumSize, partition_size - kMarginSize),
+ // Leave some space for free space jitter of a few erase
+ // blocks, in case they are needed for any individual updates
+ // to any other partition that needs to be flashed while
+ // overlayfs is in force. Of course if margin_size is not
+ // enough could normally get a flash failure, so
+ // ResizePartition() will delete the scratch partition in
+ // order to fulfill. Deleting scratch will destroy all of
+ // the adb remount overrides :-( .
+ auto margin_size = uint64_t(3 * 256 * 1024);
+ BlockDeviceInfo info;
+ if (builder->GetBlockDeviceInfo(partition_name, &info)) {
+ margin_size = 3 * info.logical_block_size;
+ }
+ partition_size = std::max(std::min(kMinimumSize, partition_size - margin_size),
partition_size / 2);
if (partition_size > partition->size()) {
if (!builder->ResizePartition(partition, partition_size)) {