Merge "liblp: Add a ResizePartition helper to MetadataBuilder."
This commit is contained in:
commit
ddcee93c01
4 changed files with 57 additions and 66 deletions
|
@ -82,11 +82,7 @@ void Partition::RemoveExtents() {
|
|||
extents_.clear();
|
||||
}
|
||||
|
||||
void Partition::ShrinkTo(uint64_t requested_size) {
|
||||
uint64_t aligned_size = AlignTo(requested_size, LP_SECTOR_SIZE);
|
||||
if (size_ <= aligned_size) {
|
||||
return;
|
||||
}
|
||||
void Partition::ShrinkTo(uint64_t aligned_size) {
|
||||
if (aligned_size == 0) {
|
||||
RemoveExtents();
|
||||
return;
|
||||
|
@ -106,7 +102,7 @@ void Partition::ShrinkTo(uint64_t requested_size) {
|
|||
sectors_to_remove -= extent->num_sectors();
|
||||
extents_.pop_back();
|
||||
}
|
||||
DCHECK(size_ == requested_size);
|
||||
DCHECK(size_ == aligned_size);
|
||||
}
|
||||
|
||||
std::unique_ptr<MetadataBuilder> MetadataBuilder::New(const std::string& block_device,
|
||||
|
@ -290,13 +286,7 @@ void MetadataBuilder::RemovePartition(const std::string& name) {
|
|||
}
|
||||
}
|
||||
|
||||
bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t requested_size) {
|
||||
// Align the space needed up to the nearest sector.
|
||||
uint64_t aligned_size = AlignTo(requested_size, LP_SECTOR_SIZE);
|
||||
if (partition->size() >= aligned_size) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t aligned_size) {
|
||||
// Figure out how much we need to allocate.
|
||||
uint64_t space_needed = aligned_size - partition->size();
|
||||
uint64_t sectors_needed = space_needed / LP_SECTOR_SIZE;
|
||||
|
@ -394,8 +384,8 @@ bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t requested_siz
|
|||
return true;
|
||||
}
|
||||
|
||||
void MetadataBuilder::ShrinkPartition(Partition* partition, uint64_t requested_size) {
|
||||
partition->ShrinkTo(requested_size);
|
||||
void MetadataBuilder::ShrinkPartition(Partition* partition, uint64_t aligned_size) {
|
||||
partition->ShrinkTo(aligned_size);
|
||||
}
|
||||
|
||||
std::unique_ptr<LpMetadata> MetadataBuilder::Export() {
|
||||
|
@ -465,5 +455,18 @@ void MetadataBuilder::set_block_device_info(const BlockDeviceInfo& device_info)
|
|||
}
|
||||
}
|
||||
|
||||
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, LP_SECTOR_SIZE);
|
||||
|
||||
if (aligned_size > partition->size()) {
|
||||
return GrowPartition(partition, aligned_size);
|
||||
}
|
||||
if (aligned_size < partition->size()) {
|
||||
ShrinkPartition(partition, aligned_size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace fs_mgr
|
||||
} // namespace android
|
||||
|
|
|
@ -45,7 +45,7 @@ TEST(liblp, ResizePartition) {
|
|||
|
||||
Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
|
||||
ASSERT_NE(system, nullptr);
|
||||
EXPECT_EQ(builder->GrowPartition(system, 65536), true);
|
||||
EXPECT_EQ(builder->ResizePartition(system, 65536), true);
|
||||
EXPECT_EQ(system->size(), 65536);
|
||||
ASSERT_EQ(system->extents().size(), 1);
|
||||
|
||||
|
@ -55,24 +55,23 @@ TEST(liblp, ResizePartition) {
|
|||
// The first logical sector will be (4096+1024*2)/512 = 12.
|
||||
EXPECT_EQ(extent->physical_sector(), 12);
|
||||
|
||||
// Test growing to the same size.
|
||||
EXPECT_EQ(builder->GrowPartition(system, 65536), true);
|
||||
// Test resizing to the same size.
|
||||
EXPECT_EQ(builder->ResizePartition(system, 65536), true);
|
||||
EXPECT_EQ(system->size(), 65536);
|
||||
EXPECT_EQ(system->extents().size(), 1);
|
||||
EXPECT_EQ(system->extents()[0]->num_sectors(), 65536 / LP_SECTOR_SIZE);
|
||||
// Test growing to a smaller size.
|
||||
EXPECT_EQ(builder->GrowPartition(system, 0), true);
|
||||
EXPECT_EQ(system->size(), 65536);
|
||||
// Test resizing to a smaller size.
|
||||
EXPECT_EQ(builder->ResizePartition(system, 0), true);
|
||||
EXPECT_EQ(system->size(), 0);
|
||||
EXPECT_EQ(system->extents().size(), 0);
|
||||
// Test resizing to a greater size.
|
||||
builder->ResizePartition(system, 131072);
|
||||
EXPECT_EQ(system->size(), 131072);
|
||||
EXPECT_EQ(system->extents().size(), 1);
|
||||
EXPECT_EQ(system->extents()[0]->num_sectors(), 65536 / LP_SECTOR_SIZE);
|
||||
// Test shrinking to a greater size.
|
||||
builder->ShrinkPartition(system, 131072);
|
||||
EXPECT_EQ(system->size(), 65536);
|
||||
EXPECT_EQ(system->extents().size(), 1);
|
||||
EXPECT_EQ(system->extents()[0]->num_sectors(), 65536 / LP_SECTOR_SIZE);
|
||||
EXPECT_EQ(system->extents()[0]->num_sectors(), 131072 / LP_SECTOR_SIZE);
|
||||
|
||||
// Test shrinking within the same extent.
|
||||
builder->ShrinkPartition(system, 32768);
|
||||
builder->ResizePartition(system, 32768);
|
||||
EXPECT_EQ(system->size(), 32768);
|
||||
EXPECT_EQ(system->extents().size(), 1);
|
||||
extent = system->extents()[0]->AsLinearExtent();
|
||||
|
@ -81,7 +80,7 @@ TEST(liblp, ResizePartition) {
|
|||
EXPECT_EQ(extent->physical_sector(), 12);
|
||||
|
||||
// Test shrinking to 0.
|
||||
builder->ShrinkPartition(system, 0);
|
||||
builder->ResizePartition(system, 0);
|
||||
EXPECT_EQ(system->size(), 0);
|
||||
EXPECT_EQ(system->extents().size(), 0);
|
||||
}
|
||||
|
@ -92,11 +91,11 @@ TEST(liblp, PartitionAlignment) {
|
|||
// Test that we align up to one sector.
|
||||
Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
|
||||
ASSERT_NE(system, nullptr);
|
||||
EXPECT_EQ(builder->GrowPartition(system, 10000), true);
|
||||
EXPECT_EQ(builder->ResizePartition(system, 10000), true);
|
||||
EXPECT_EQ(system->size(), 10240);
|
||||
EXPECT_EQ(system->extents().size(), 1);
|
||||
|
||||
builder->ShrinkPartition(system, 9000);
|
||||
builder->ResizePartition(system, 9000);
|
||||
EXPECT_EQ(system->size(), 9216);
|
||||
EXPECT_EQ(system->extents().size(), 1);
|
||||
}
|
||||
|
@ -174,8 +173,8 @@ TEST(liblp, InternalPartitionAlignment) {
|
|||
|
||||
// Add a bunch of small extents to each, interleaving.
|
||||
for (size_t i = 0; i < 10; i++) {
|
||||
ASSERT_TRUE(builder->GrowPartition(a, a->size() + 4096));
|
||||
ASSERT_TRUE(builder->GrowPartition(b, b->size() + 4096));
|
||||
ASSERT_TRUE(builder->ResizePartition(a, a->size() + 4096));
|
||||
ASSERT_TRUE(builder->ResizePartition(b, b->size() + 4096));
|
||||
}
|
||||
EXPECT_EQ(a->size(), 40960);
|
||||
EXPECT_EQ(b->size(), 40960);
|
||||
|
@ -203,9 +202,9 @@ TEST(liblp, UseAllDiskSpace) {
|
|||
|
||||
Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
|
||||
ASSERT_NE(system, nullptr);
|
||||
EXPECT_EQ(builder->GrowPartition(system, 1036288), true);
|
||||
EXPECT_EQ(builder->ResizePartition(system, 1036288), true);
|
||||
EXPECT_EQ(system->size(), 1036288);
|
||||
EXPECT_EQ(builder->GrowPartition(system, 1036289), false);
|
||||
EXPECT_EQ(builder->ResizePartition(system, 1036289), false);
|
||||
}
|
||||
|
||||
TEST(liblp, BuildComplex) {
|
||||
|
@ -215,9 +214,9 @@ TEST(liblp, BuildComplex) {
|
|||
Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY);
|
||||
ASSERT_NE(system, nullptr);
|
||||
ASSERT_NE(vendor, nullptr);
|
||||
EXPECT_EQ(builder->GrowPartition(system, 65536), true);
|
||||
EXPECT_EQ(builder->GrowPartition(vendor, 32768), true);
|
||||
EXPECT_EQ(builder->GrowPartition(system, 98304), true);
|
||||
EXPECT_EQ(builder->ResizePartition(system, 65536), true);
|
||||
EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
|
||||
EXPECT_EQ(builder->ResizePartition(system, 98304), true);
|
||||
EXPECT_EQ(system->size(), 98304);
|
||||
EXPECT_EQ(vendor->size(), 32768);
|
||||
|
||||
|
@ -268,9 +267,9 @@ TEST(liblp, BuilderExport) {
|
|||
Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY);
|
||||
ASSERT_NE(system, nullptr);
|
||||
ASSERT_NE(vendor, nullptr);
|
||||
EXPECT_EQ(builder->GrowPartition(system, 65536), true);
|
||||
EXPECT_EQ(builder->GrowPartition(vendor, 32768), true);
|
||||
EXPECT_EQ(builder->GrowPartition(system, 98304), true);
|
||||
EXPECT_EQ(builder->ResizePartition(system, 65536), true);
|
||||
EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
|
||||
EXPECT_EQ(builder->ResizePartition(system, 98304), true);
|
||||
|
||||
unique_ptr<LpMetadata> exported = builder->Export();
|
||||
EXPECT_NE(exported, nullptr);
|
||||
|
@ -323,9 +322,9 @@ TEST(liblp, BuilderImport) {
|
|||
Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY);
|
||||
ASSERT_NE(system, nullptr);
|
||||
ASSERT_NE(vendor, nullptr);
|
||||
EXPECT_EQ(builder->GrowPartition(system, 65536), true);
|
||||
EXPECT_EQ(builder->GrowPartition(vendor, 32768), true);
|
||||
EXPECT_EQ(builder->GrowPartition(system, 98304), true);
|
||||
EXPECT_EQ(builder->ResizePartition(system, 65536), true);
|
||||
EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
|
||||
EXPECT_EQ(builder->ResizePartition(system, 98304), true);
|
||||
|
||||
unique_ptr<LpMetadata> exported = builder->Export();
|
||||
ASSERT_NE(exported, nullptr);
|
||||
|
|
|
@ -162,29 +162,17 @@ class MetadataBuilder {
|
|||
// Find a partition by name. If no partition is found, nullptr is returned.
|
||||
Partition* FindPartition(const std::string& name);
|
||||
|
||||
// Grow a partition to the requested size. If the partition's size is already
|
||||
// greater or equal to the requested size, this will return true and the
|
||||
// partition table will not be changed. Otherwise, a greedy algorithm is
|
||||
// used to find free gaps in the partition table and allocate them for this
|
||||
// partition. If not enough space can be allocated, false is returned, and
|
||||
// the parition table will not be modified.
|
||||
// Grow or shrink a partition to the requested size. This size will be
|
||||
// rounded UP to the nearest block (512 bytes).
|
||||
//
|
||||
// The size will be rounded UP to the nearest sector.
|
||||
// When growing a partition, a greedy algorithm is used to find free gaps
|
||||
// in the partition table and allocate them. If not enough space can be
|
||||
// allocated, false is returned, and the parition table will not be
|
||||
// modified.
|
||||
//
|
||||
// Note, this is an in-memory operation, and it does not alter the
|
||||
// underlying filesystem or contents of the partition on disk.
|
||||
bool GrowPartition(Partition* partition, uint64_t requested_size);
|
||||
|
||||
// Shrink a partition to the requested size. If the partition is already
|
||||
// smaller than the given size, this will return and the partition table
|
||||
// will not be changed. Otherwise, extents will be removed and/or shrunk
|
||||
// from the end of the partition until it is the requested size.
|
||||
//
|
||||
// The size will be rounded UP to the nearest sector.
|
||||
//
|
||||
// Note, this is an in-memory operation, and it does not alter the
|
||||
// underlying filesystem or contents of the partition on disk.
|
||||
void ShrinkPartition(Partition* partition, uint64_t requested_size);
|
||||
bool ResizePartition(Partition* partition, uint64_t requested_size);
|
||||
|
||||
// Amount of space that can be allocated to logical partitions.
|
||||
uint64_t AllocatableSpace() const;
|
||||
|
@ -198,7 +186,8 @@ class MetadataBuilder {
|
|||
MetadataBuilder();
|
||||
bool Init(const BlockDeviceInfo& info, uint32_t metadata_max_size, uint32_t metadata_slot_count);
|
||||
bool Init(const LpMetadata& metadata);
|
||||
|
||||
bool GrowPartition(Partition* partition, uint64_t aligned_size);
|
||||
void ShrinkPartition(Partition* partition, uint64_t aligned_size);
|
||||
uint64_t AlignSector(uint64_t sector);
|
||||
|
||||
LpMetadataGeometry geometry_;
|
||||
|
|
|
@ -85,7 +85,7 @@ static bool AddDefaultPartitions(MetadataBuilder* builder) {
|
|||
if (!system) {
|
||||
return false;
|
||||
}
|
||||
return builder->GrowPartition(system, 24 * 1024);
|
||||
return builder->ResizePartition(system, 24 * 1024);
|
||||
}
|
||||
|
||||
// Create a temporary disk and flash it with the default partition setup.
|
||||
|
@ -345,7 +345,7 @@ TEST(liblp, TooManyPartitions) {
|
|||
ASSERT_NE(partition, nullptr);
|
||||
// Add one extent to any partition to fill up more space - we're at 508
|
||||
// bytes after this, out of 512.
|
||||
ASSERT_TRUE(builder->GrowPartition(partition, 1024));
|
||||
ASSERT_TRUE(builder->ResizePartition(partition, 1024));
|
||||
|
||||
unique_ptr<LpMetadata> exported = builder->Export();
|
||||
ASSERT_NE(exported, nullptr);
|
||||
|
|
Loading…
Reference in a new issue