Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8cf1e38b authored by David Anderson's avatar David Anderson
Browse files

liblp: Force more sizes to be a multiple of the sector size.

This makes offset calculations and library interactions much easier.

Bug: 79173901
Test: liblp_test gtest
Change-Id: I595c5435bd6bc166693a434ecdcd2d098185f963
parent 4813823e
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -200,6 +200,11 @@ bool MetadataBuilder::Init(const BlockDeviceInfo& device_info, uint32_t metadata
    metadata_max_size = AlignTo(metadata_max_size, LP_SECTOR_SIZE);

    // Check that device properties are sane.
    device_info_ = device_info;
    if (device_info_.size % LP_SECTOR_SIZE != 0) {
        LERROR << "Block device size must be a multiple of 512.";
        return false;
    }
    if (device_info_.alignment_offset % LP_SECTOR_SIZE != 0) {
        LERROR << "Alignment offset is not sector-aligned.";
        return false;
@@ -212,7 +217,6 @@ bool MetadataBuilder::Init(const BlockDeviceInfo& device_info, uint32_t metadata
        LERROR << "Partition alignment offset is greater than its alignment.";
        return false;
    }
    device_info_ = device_info;

    // We reserve a geometry block (4KB) plus space for each copy of the
    // maximum size of a metadata blob. Then, we double that space since
+3 −18
Original line number Diff line number Diff line
@@ -106,19 +106,9 @@ TEST(liblp, DiskAlignment) {
    static const uint32_t kMetadataSize = 1024;
    static const uint32_t kMetadataSlots = 2;

    // If the disk size is not aligned to 512 bytes, make sure it still leaves
    // space at the end for backup metadata, and that it doesn't overlap with
    // the space for logical partitions.
    unique_ptr<MetadataBuilder> builder =
            MetadataBuilder::New(kDiskSize, kMetadataSize, kMetadataSlots);
    unique_ptr<LpMetadata> exported = builder->Export();
    ASSERT_NE(exported, nullptr);

    static const size_t kMetadataSpace =
            (kMetadataSize * kMetadataSlots) + LP_METADATA_GEOMETRY_SIZE;
    uint64_t space_at_end =
            kDiskSize - (exported->geometry.last_logical_sector + 1) * LP_SECTOR_SIZE;
    EXPECT_GE(space_at_end, kMetadataSpace);
    ASSERT_EQ(builder, nullptr);
}

TEST(liblp, MetadataAlignment) {
@@ -148,15 +138,10 @@ TEST(liblp, InternalAlignment) {
    EXPECT_EQ(exported->geometry.first_logical_sector, 1472);
    EXPECT_EQ(exported->geometry.last_logical_sector, 2035);

    // Test only an alignment offset (which should simply bump up the first
    // logical sector).
    // Alignment offset without alignment doesn't mean anything.
    device_info.alignment = 0;
    builder = MetadataBuilder::New(device_info, 1024, 2);
    ASSERT_NE(builder, nullptr);
    exported = builder->Export();
    ASSERT_NE(exported, nullptr);
    EXPECT_EQ(exported->geometry.first_logical_sector, 1484);
    EXPECT_EQ(exported->geometry.last_logical_sector, 2035);
    ASSERT_EQ(builder, nullptr);

    // Test a small alignment with an alignment offset.
    device_info.alignment = 12 * 1024;
+3 −1
Original line number Diff line number Diff line
@@ -86,7 +86,9 @@ typedef struct LpMetadataGeometry {
    /*  8: SHA256 checksum of this struct, with this field set to 0. */
    uint8_t checksum[32];

    /* 40: Maximum amount of space a single copy of the metadata can use. */
    /* 40: Maximum amount of space a single copy of the metadata can use. This
     * must be a multiple of LP_SECTOR_SIZE.
     */
    uint32_t metadata_max_size;

    /* 44: Number of copies of the metadata to keep. For A/B devices, this
+4 −0
Original line number Diff line number Diff line
@@ -68,6 +68,10 @@ static bool ParseGeometry(const void* buffer, LpMetadataGeometry* geometry) {
        LERROR << "Logical partition metadata has invalid slot count.";
        return false;
    }
    if (geometry->metadata_max_size % LP_SECTOR_SIZE != 0) {
        LERROR << "Metadata max size is not sector-aligned.";
        return false;
    }

    // Check that the metadata area and logical partition areas don't overlap.
    int64_t end_of_metadata =