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

Commit d20d3e18 authored by David Anderson's avatar David Anderson Committed by android-build-merger
Browse files

Merge changes Ib244a98f,Ib173f251 am: 0730260a am: 612c3909

am: 3be2289d

Change-Id: Ic301e5caa40cc79d66a688e94ba5604d04cc8dec
parents b2c8289a 3be2289d
Loading
Loading
Loading
Loading
+38 −30
Original line number Diff line number Diff line
@@ -150,7 +150,7 @@ std::unique_ptr<MetadataBuilder> MetadataBuilder::New(const std::string& block_d
    }
    BlockDeviceInfo device_info;
    if (fs_mgr::GetBlockDeviceInfo(block_device, &device_info)) {
        builder->set_block_device_info(device_info);
        builder->UpdateBlockDeviceInfo(device_info);
    }
    return builder;
}
@@ -217,10 +217,6 @@ bool MetadataBuilder::Init(const LpMetadata& metadata) {
            }
        }
    }

    device_info_.alignment = geometry_.alignment;
    device_info_.alignment_offset = geometry_.alignment_offset;
    device_info_.logical_block_size = geometry_.logical_block_size;
    return true;
}

@@ -239,24 +235,23 @@ 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) {
    if (device_info.size % LP_SECTOR_SIZE != 0) {
        LERROR << "Block device size must be a multiple of 512.";
        return false;
    }
    if (device_info_.logical_block_size % LP_SECTOR_SIZE != 0) {
    if (device_info.logical_block_size % LP_SECTOR_SIZE != 0) {
        LERROR << "Logical block size must be a multiple of 512.";
        return false;
    }
    if (device_info_.alignment_offset % LP_SECTOR_SIZE != 0) {
    if (device_info.alignment_offset % LP_SECTOR_SIZE != 0) {
        LERROR << "Alignment offset is not sector-aligned.";
        return false;
    }
    if (device_info_.alignment % LP_SECTOR_SIZE != 0) {
    if (device_info.alignment % LP_SECTOR_SIZE != 0) {
        LERROR << "Partition alignment is not sector-aligned.";
        return false;
    }
    if (device_info_.alignment_offset > device_info_.alignment) {
    if (device_info.alignment_offset > device_info.alignment) {
        LERROR << "Partition alignment offset is greater than its alignment.";
        return false;
    }
@@ -267,20 +262,21 @@ bool MetadataBuilder::Init(const BlockDeviceInfo& device_info, uint32_t metadata
    uint64_t reserved =
            LP_METADATA_GEOMETRY_SIZE + (uint64_t(metadata_max_size) * metadata_slot_count);
    uint64_t total_reserved = reserved * 2;
    if (device_info_.size < total_reserved) {
    if (device_info.size < total_reserved) {
        LERROR << "Attempting to create metadata on a block device that is too small.";
        return false;
    }

    // Compute the first free sector, factoring in alignment.
    uint64_t free_area = AlignTo(reserved, device_info_.alignment, device_info_.alignment_offset);
    uint64_t free_area =
            AlignTo(total_reserved, device_info.alignment, device_info.alignment_offset);
    uint64_t first_sector = free_area / LP_SECTOR_SIZE;

    // Compute the last free sector, which is inclusive. We subtract 1 to make
    // sure that logical partitions won't overlap with the same sector as the
    // backup metadata, which could happen if the block device was not aligned
    // to LP_SECTOR_SIZE.
    uint64_t last_sector = ((device_info_.size - reserved) / LP_SECTOR_SIZE) - 1;
    uint64_t last_sector = (device_info.size / LP_SECTOR_SIZE) - 1;

    // If this check fails, it means either (1) we did not have free space to
    // allocate a single sector, or (2) we did, but the alignment was high
@@ -296,7 +292,7 @@ bool MetadataBuilder::Init(const BlockDeviceInfo& device_info, uint32_t metadata
    // computation, then we abort. Note that the last sector is inclusive,
    // so we have to account for that.
    uint64_t num_free_sectors = last_sector - first_sector + 1;
    uint64_t sectors_per_block = device_info_.logical_block_size / LP_SECTOR_SIZE;
    uint64_t sectors_per_block = device_info.logical_block_size / LP_SECTOR_SIZE;
    if (num_free_sectors < sectors_per_block) {
        LERROR << "Not enough space to allocate any partition tables.";
        return false;
@@ -307,9 +303,9 @@ bool MetadataBuilder::Init(const BlockDeviceInfo& device_info, uint32_t metadata
    geometry_.last_logical_sector = last_sector;
    geometry_.metadata_max_size = metadata_max_size;
    geometry_.metadata_slot_count = metadata_slot_count;
    geometry_.alignment = device_info_.alignment;
    geometry_.alignment_offset = device_info_.alignment_offset;
    geometry_.block_device_size = device_info_.size;
    geometry_.alignment = device_info.alignment;
    geometry_.alignment_offset = device_info.alignment_offset;
    geometry_.block_device_size = device_info.size;
    geometry_.logical_block_size = device_info.logical_block_size;

    if (!AddGroup("default", 0)) {
@@ -460,7 +456,7 @@ bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t aligned_size)
        free_regions.emplace_back(last_free_extent_start, geometry_.last_logical_sector + 1);
    }

    const uint64_t sectors_per_block = device_info_.logical_block_size / LP_SECTOR_SIZE;
    const uint64_t sectors_per_block = geometry_.logical_block_size / LP_SECTOR_SIZE;
    CHECK_NE(sectors_per_block, 0);
    CHECK(sectors_needed % sectors_per_block == 0);

@@ -578,32 +574,44 @@ uint64_t MetadataBuilder::AlignSector(uint64_t sector) {
    // Note: when reading alignment info from the Kernel, we don't assume it
    // is aligned to the sector size, so we round up to the nearest sector.
    uint64_t lba = sector * LP_SECTOR_SIZE;
    uint64_t aligned = AlignTo(lba, device_info_.alignment, device_info_.alignment_offset);
    uint64_t aligned = AlignTo(lba, geometry_.alignment, geometry_.alignment_offset);
    return AlignTo(aligned, LP_SECTOR_SIZE) / LP_SECTOR_SIZE;
}

void MetadataBuilder::set_block_device_info(const BlockDeviceInfo& device_info) {
    device_info_.size = device_info.size;
bool MetadataBuilder::GetBlockDeviceInfo(BlockDeviceInfo* info) const {
    info->size = geometry_.block_device_size;
    info->alignment = geometry_.alignment;
    info->alignment_offset = geometry_.alignment_offset;
    info->logical_block_size = geometry_.logical_block_size;
    return true;
}

    // Note that if the logical block size changes, we're probably in trouble:
    // we could have already built extents that will only work on the previous
    // size.
    DCHECK(partitions_.empty() ||
           device_info_.logical_block_size == device_info.logical_block_size);
bool MetadataBuilder::UpdateBlockDeviceInfo(const BlockDeviceInfo& device_info) {
    if (device_info.size != geometry_.block_device_size) {
        LERROR << "Device size does not match (got " << device_info.size << ", expected "
               << geometry_.block_device_size << ")";
        return false;
    }
    if (device_info.logical_block_size != geometry_.logical_block_size) {
        LERROR << "Device logical block size does not match (got " << device_info.logical_block_size
               << ", expected " << geometry_.logical_block_size << ")";
        return false;
    }

    // The kernel does not guarantee these values are present, so we only
    // replace existing values if the new values are non-zero.
    if (device_info.alignment) {
        device_info_.alignment = device_info.alignment;
        geometry_.alignment = device_info.alignment;
    }
    if (device_info.alignment_offset) {
        device_info_.alignment_offset = device_info.alignment_offset;
        geometry_.alignment_offset = device_info.alignment_offset;
    }
    return true;
}

bool MetadataBuilder::ResizePartition(Partition* partition, uint64_t requested_size) {
    // Align the space needed up to the nearest sector.
    uint64_t aligned_size = AlignTo(requested_size, device_info_.logical_block_size);
    uint64_t aligned_size = AlignTo(requested_size, geometry_.logical_block_size);
    uint64_t old_size = partition->size();

    if (aligned_size > old_size) {
+42 −29
Original line number Diff line number Diff line
@@ -48,8 +48,8 @@ TEST(liblp, ResizePartition) {
    LinearExtent* extent = system->extents()[0]->AsLinearExtent();
    ASSERT_NE(extent, nullptr);
    EXPECT_EQ(extent->num_sectors(), 65536 / LP_SECTOR_SIZE);
    // The first logical sector will be (4096+1024*2)/512 = 12.
    EXPECT_EQ(extent->physical_sector(), 12);
    // The first logical sector will be (8192+1024*4)/512 = 12.
    EXPECT_EQ(extent->physical_sector(), 24);

    // Test resizing to the same size.
    EXPECT_EQ(builder->ResizePartition(system, 65536), true);
@@ -78,7 +78,7 @@ TEST(liblp, ResizePartition) {
    extent = system->extents()[0]->AsLinearExtent();
    ASSERT_NE(extent, nullptr);
    EXPECT_EQ(extent->num_sectors(), 32768 / LP_SECTOR_SIZE);
    EXPECT_EQ(extent->physical_sector(), 12);
    EXPECT_EQ(extent->physical_sector(), 24);

    // Test shrinking to 0.
    builder->ResizePartition(system, 0);
@@ -127,7 +127,7 @@ TEST(liblp, InternalAlignment) {
    unique_ptr<LpMetadata> exported = builder->Export();
    ASSERT_NE(exported, nullptr);
    EXPECT_EQ(exported->geometry.first_logical_sector, 1536);
    EXPECT_EQ(exported->geometry.last_logical_sector, 2031);
    EXPECT_EQ(exported->geometry.last_logical_sector, 2047);

    // Test a large alignment offset thrown in.
    device_info.alignment_offset = 753664;
@@ -136,7 +136,7 @@ TEST(liblp, InternalAlignment) {
    exported = builder->Export();
    ASSERT_NE(exported, nullptr);
    EXPECT_EQ(exported->geometry.first_logical_sector, 1472);
    EXPECT_EQ(exported->geometry.last_logical_sector, 2031);
    EXPECT_EQ(exported->geometry.last_logical_sector, 2047);

    // Alignment offset without alignment doesn't mean anything.
    device_info.alignment = 0;
@@ -150,8 +150,8 @@ TEST(liblp, InternalAlignment) {
    ASSERT_NE(builder, nullptr);
    exported = builder->Export();
    ASSERT_NE(exported, nullptr);
    EXPECT_EQ(exported->geometry.first_logical_sector, 78);
    EXPECT_EQ(exported->geometry.last_logical_sector, 1973);
    EXPECT_EQ(exported->geometry.first_logical_sector, 150);
    EXPECT_EQ(exported->geometry.last_logical_sector, 2045);

    // Test a small alignment with no alignment offset.
    device_info.alignment = 11 * 1024;
@@ -159,8 +159,8 @@ TEST(liblp, InternalAlignment) {
    ASSERT_NE(builder, nullptr);
    exported = builder->Export();
    ASSERT_NE(exported, nullptr);
    EXPECT_EQ(exported->geometry.first_logical_sector, 72);
    EXPECT_EQ(exported->geometry.last_logical_sector, 1975);
    EXPECT_EQ(exported->geometry.first_logical_sector, 160);
    EXPECT_EQ(exported->geometry.last_logical_sector, 2047);
}

TEST(liblp, InternalPartitionAlignment) {
@@ -247,11 +247,11 @@ TEST(liblp, BuildComplex) {
    ASSERT_NE(system2, nullptr);
    ASSERT_NE(vendor1, nullptr);
    EXPECT_EQ(system1->num_sectors(), 65536 / LP_SECTOR_SIZE);
    EXPECT_EQ(system1->physical_sector(), 12);
    EXPECT_EQ(system1->physical_sector(), 24);
    EXPECT_EQ(system2->num_sectors(), 32768 / LP_SECTOR_SIZE);
    EXPECT_EQ(system2->physical_sector(), 204);
    EXPECT_EQ(system2->physical_sector(), 216);
    EXPECT_EQ(vendor1->num_sectors(), 32768 / LP_SECTOR_SIZE);
    EXPECT_EQ(vendor1->physical_sector(), 140);
    EXPECT_EQ(vendor1->physical_sector(), 152);
    EXPECT_EQ(system1->physical_sector() + system1->num_sectors(), vendor1->physical_sector());
    EXPECT_EQ(vendor1->physical_sector() + vendor1->num_sectors(), system2->physical_sector());
}
@@ -297,13 +297,11 @@ TEST(liblp, BuilderExport) {
    EXPECT_EQ(geometry.struct_size, sizeof(geometry));
    EXPECT_EQ(geometry.metadata_max_size, 1024);
    EXPECT_EQ(geometry.metadata_slot_count, 2);
    EXPECT_EQ(geometry.first_logical_sector, 12);
    EXPECT_EQ(geometry.last_logical_sector, 2035);
    EXPECT_EQ(geometry.first_logical_sector, 24);
    EXPECT_EQ(geometry.last_logical_sector, 2047);

    static const size_t kMetadataSpace =
            (kMetadataSize * kMetadataSlots) + LP_METADATA_GEOMETRY_SIZE;
    uint64_t space_at_end = kDiskSize - (geometry.last_logical_sector + 1) * LP_SECTOR_SIZE;
    EXPECT_GE(space_at_end, kMetadataSpace);
            ((kMetadataSize * kMetadataSlots) + LP_METADATA_GEOMETRY_SIZE) * 2;
    EXPECT_GE(geometry.first_logical_sector * LP_SECTOR_SIZE, kMetadataSpace);

    // Verify header.
@@ -361,9 +359,9 @@ TEST(liblp, BuilderImport) {
    LinearExtent* system2 = system->extents()[1]->AsLinearExtent();
    LinearExtent* vendor1 = vendor->extents()[0]->AsLinearExtent();
    EXPECT_EQ(system1->num_sectors(), 65536 / LP_SECTOR_SIZE);
    EXPECT_EQ(system1->physical_sector(), 12);
    EXPECT_EQ(system1->physical_sector(), 24);
    EXPECT_EQ(system2->num_sectors(), 32768 / LP_SECTOR_SIZE);
    EXPECT_EQ(system2->physical_sector(), 204);
    EXPECT_EQ(system2->physical_sector(), 216);
    EXPECT_EQ(vendor1->num_sectors(), 32768 / LP_SECTOR_SIZE);
}

@@ -437,22 +435,37 @@ TEST(liblp, UpdateBlockDeviceInfo) {
    unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
    ASSERT_NE(builder, nullptr);

    EXPECT_EQ(builder->block_device_info().size, device_info.size);
    EXPECT_EQ(builder->block_device_info().alignment, device_info.alignment);
    EXPECT_EQ(builder->block_device_info().alignment_offset, device_info.alignment_offset);
    EXPECT_EQ(builder->block_device_info().logical_block_size, device_info.logical_block_size);
    BlockDeviceInfo new_info;
    ASSERT_TRUE(builder->GetBlockDeviceInfo(&new_info));

    EXPECT_EQ(new_info.size, device_info.size);
    EXPECT_EQ(new_info.alignment, device_info.alignment);
    EXPECT_EQ(new_info.alignment_offset, device_info.alignment_offset);
    EXPECT_EQ(new_info.logical_block_size, device_info.logical_block_size);

    device_info.alignment = 0;
    device_info.alignment_offset = 2048;
    builder->set_block_device_info(device_info);
    EXPECT_EQ(builder->block_device_info().alignment, 4096);
    EXPECT_EQ(builder->block_device_info().alignment_offset, device_info.alignment_offset);
    ASSERT_TRUE(builder->UpdateBlockDeviceInfo(device_info));
    ASSERT_TRUE(builder->GetBlockDeviceInfo(&new_info));
    EXPECT_EQ(new_info.alignment, 4096);
    EXPECT_EQ(new_info.alignment_offset, device_info.alignment_offset);

    device_info.alignment = 8192;
    device_info.alignment_offset = 0;
    builder->set_block_device_info(device_info);
    EXPECT_EQ(builder->block_device_info().alignment, 8192);
    EXPECT_EQ(builder->block_device_info().alignment_offset, 2048);
    ASSERT_TRUE(builder->UpdateBlockDeviceInfo(device_info));
    ASSERT_TRUE(builder->GetBlockDeviceInfo(&new_info));
    EXPECT_EQ(new_info.alignment, 8192);
    EXPECT_EQ(new_info.alignment_offset, 2048);

    new_info.size += 4096;
    ASSERT_FALSE(builder->UpdateBlockDeviceInfo(new_info));
    ASSERT_TRUE(builder->GetBlockDeviceInfo(&new_info));
    EXPECT_EQ(new_info.size, 1024 * 1024);

    new_info.logical_block_size = 512;
    ASSERT_FALSE(builder->UpdateBlockDeviceInfo(new_info));
    ASSERT_TRUE(builder->GetBlockDeviceInfo(&new_info));
    EXPECT_EQ(new_info.logical_block_size, 4096);
}

TEST(liblp, InvalidBlockSize) {
+5 −20
Original line number Diff line number Diff line
@@ -167,16 +167,12 @@ bool SparseBuilder::Build() {
    std::string metadata_blob = SerializeMetadata(metadata_);
    metadata_blob.resize(geometry_.metadata_max_size);

    std::string all_metadata;
    for (size_t i = 0; i < geometry_.metadata_slot_count; i++) {
        all_metadata += metadata_blob;
    // Two copies of geometry, then two copies of each metadata slot.
    all_metadata_ += geometry_blob + geometry_blob;
    for (size_t i = 0; i < geometry_.metadata_slot_count * 2; i++) {
        all_metadata_ += metadata_blob;
    }

    // Metadata immediately follows geometry, and we write the same metadata
    // to all slots. Note that we don't bother trying to write skip chunks
    // here since it's a small amount of data.
    primary_blob_ = geometry_blob + all_metadata;
    if (!AddData(primary_blob_, 0)) {
    if (!AddData(all_metadata_, 0)) {
        return false;
    }

@@ -195,17 +191,6 @@ bool SparseBuilder::Build() {
        LERROR << "Partition image was specified but no partition was found.";
        return false;
    }

    // The backup area contains all metadata slots, and then geometry. Similar
    // to before we write the metadata to every slot.
    int64_t backup_offset = GetBackupMetadataOffset(geometry_, 0);
    int64_t backups_start = static_cast<int64_t>(geometry_.block_device_size) + backup_offset;
    int64_t backup_sector = backups_start / LP_SECTOR_SIZE;

    backup_blob_ = all_metadata + geometry_blob;
    if (!AddData(backup_blob_, backup_sector)) {
        return false;
    }
    return true;
}

+1 −2
Original line number Diff line number Diff line
@@ -56,8 +56,7 @@ class SparseBuilder {
    const LpMetadataGeometry& geometry_;
    uint32_t block_size_;
    std::unique_ptr<sparse_file, decltype(&sparse_file_destroy)> file_;
    std::string primary_blob_;
    std::string backup_blob_;
    std::string all_metadata_;
    std::map<std::string, std::string> images_;
    std::vector<android::base::unique_fd> temp_fds_;
};
+2 −5
Original line number Diff line number Diff line
@@ -215,10 +215,8 @@ class MetadataBuilder {
    uint64_t AllocatableSpace() const;
    uint64_t UsedSpace() const;

    // Merge new block device information into previous values. Alignment values
    // are only overwritten if the new values are non-zero.
    void set_block_device_info(const BlockDeviceInfo& device_info);
    const BlockDeviceInfo& block_device_info() const { return device_info_; }
    bool GetBlockDeviceInfo(BlockDeviceInfo* info) const;
    bool UpdateBlockDeviceInfo(const BlockDeviceInfo& info);

  private:
    MetadataBuilder();
@@ -238,7 +236,6 @@ class MetadataBuilder {
    LpMetadataHeader header_;
    std::vector<std::unique_ptr<Partition>> partitions_;
    std::vector<std::unique_ptr<PartitionGroup>> groups_;
    BlockDeviceInfo device_info_;
};

// Read BlockDeviceInfo for a given block device. This always returns false
Loading