summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Anderson2018-07-31 15:34:14 -0500
committerDavid Anderson2018-08-01 19:41:29 -0500
commit2e755e38af9e73b802c229e88a3de4e48eaff805 (patch)
treef37784a345dee91b90e6aef8be5c8c86329af9b9
parentd5f825c78bc98027a485d8bdecd14e8563a449ba (diff)
downloadplatform-system-core-2e755e38af9e73b802c229e88a3de4e48eaff805.tar.gz
platform-system-core-2e755e38af9e73b802c229e88a3de4e48eaff805.tar.xz
platform-system-core-2e755e38af9e73b802c229e88a3de4e48eaff805.zip
liblp: Add a ResizePartition helper to MetadataBuilder.
This change is to assist with implementing the fastbootd "resize-partition" command. The GrowPartition and ShrinkPartition functions are now private. Bug: 78793464 Test: N/A Change-Id: Ic66a3052359e2558663272ff6e014704206b197e
-rw-r--r--fs_mgr/liblp/builder.cpp33
-rw-r--r--fs_mgr/liblp/builder_test.cpp57
-rw-r--r--fs_mgr/liblp/include/liblp/builder.h29
-rw-r--r--fs_mgr/liblp/io_test.cpp4
4 files changed, 57 insertions, 66 deletions
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index 9d710f90b..d6eee6b32 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -82,11 +82,7 @@ void Partition::RemoveExtents() {
82 extents_.clear(); 82 extents_.clear();
83} 83}
84 84
85void Partition::ShrinkTo(uint64_t requested_size) { 85void Partition::ShrinkTo(uint64_t aligned_size) {
86 uint64_t aligned_size = AlignTo(requested_size, LP_SECTOR_SIZE);
87 if (size_ <= aligned_size) {
88 return;
89 }
90 if (aligned_size == 0) { 86 if (aligned_size == 0) {
91 RemoveExtents(); 87 RemoveExtents();
92 return; 88 return;
@@ -106,7 +102,7 @@ void Partition::ShrinkTo(uint64_t requested_size) {
106 sectors_to_remove -= extent->num_sectors(); 102 sectors_to_remove -= extent->num_sectors();
107 extents_.pop_back(); 103 extents_.pop_back();
108 } 104 }
109 DCHECK(size_ == requested_size); 105 DCHECK(size_ == aligned_size);
110} 106}
111 107
112std::unique_ptr<MetadataBuilder> MetadataBuilder::New(const std::string& block_device, 108std::unique_ptr<MetadataBuilder> MetadataBuilder::New(const std::string& block_device,
@@ -290,13 +286,7 @@ void MetadataBuilder::RemovePartition(const std::string& name) {
290 } 286 }
291} 287}
292 288
293bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t requested_size) { 289bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t aligned_size) {
294 // Align the space needed up to the nearest sector.
295 uint64_t aligned_size = AlignTo(requested_size, LP_SECTOR_SIZE);
296 if (partition->size() >= aligned_size) {
297 return true;
298 }
299
300 // Figure out how much we need to allocate. 290 // Figure out how much we need to allocate.
301 uint64_t space_needed = aligned_size - partition->size(); 291 uint64_t space_needed = aligned_size - partition->size();
302 uint64_t sectors_needed = space_needed / LP_SECTOR_SIZE; 292 uint64_t sectors_needed = space_needed / LP_SECTOR_SIZE;
@@ -394,8 +384,8 @@ bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t requested_siz
394 return true; 384 return true;
395} 385}
396 386
397void MetadataBuilder::ShrinkPartition(Partition* partition, uint64_t requested_size) { 387void MetadataBuilder::ShrinkPartition(Partition* partition, uint64_t aligned_size) {
398 partition->ShrinkTo(requested_size); 388 partition->ShrinkTo(aligned_size);
399} 389}
400 390
401std::unique_ptr<LpMetadata> MetadataBuilder::Export() { 391std::unique_ptr<LpMetadata> MetadataBuilder::Export() {
@@ -465,5 +455,18 @@ void MetadataBuilder::set_block_device_info(const BlockDeviceInfo& device_info)
465 } 455 }
466} 456}
467 457
458bool MetadataBuilder::ResizePartition(Partition* partition, uint64_t requested_size) {
459 // Align the space needed up to the nearest sector.
460 uint64_t aligned_size = AlignTo(requested_size, LP_SECTOR_SIZE);
461
462 if (aligned_size > partition->size()) {
463 return GrowPartition(partition, aligned_size);
464 }
465 if (aligned_size < partition->size()) {
466 ShrinkPartition(partition, aligned_size);
467 }
468 return true;
469}
470
468} // namespace fs_mgr 471} // namespace fs_mgr
469} // namespace android 472} // namespace android
diff --git a/fs_mgr/liblp/builder_test.cpp b/fs_mgr/liblp/builder_test.cpp
index b610fd4c4..4334d51a5 100644
--- a/fs_mgr/liblp/builder_test.cpp
+++ b/fs_mgr/liblp/builder_test.cpp
@@ -45,7 +45,7 @@ TEST(liblp, ResizePartition) {
45 45
46 Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY); 46 Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
47 ASSERT_NE(system, nullptr); 47 ASSERT_NE(system, nullptr);
48 EXPECT_EQ(builder->GrowPartition(system, 65536), true); 48 EXPECT_EQ(builder->ResizePartition(system, 65536), true);
49 EXPECT_EQ(system->size(), 65536); 49 EXPECT_EQ(system->size(), 65536);
50 ASSERT_EQ(system->extents().size(), 1); 50 ASSERT_EQ(system->extents().size(), 1);
51 51
@@ -55,24 +55,23 @@ TEST(liblp, ResizePartition) {
55 // The first logical sector will be (4096+1024*2)/512 = 12. 55 // The first logical sector will be (4096+1024*2)/512 = 12.
56 EXPECT_EQ(extent->physical_sector(), 12); 56 EXPECT_EQ(extent->physical_sector(), 12);
57 57
58 // Test growing to the same size. 58 // Test resizing to the same size.
59 EXPECT_EQ(builder->GrowPartition(system, 65536), true); 59 EXPECT_EQ(builder->ResizePartition(system, 65536), true);
60 EXPECT_EQ(system->size(), 65536); 60 EXPECT_EQ(system->size(), 65536);
61 EXPECT_EQ(system->extents().size(), 1); 61 EXPECT_EQ(system->extents().size(), 1);
62 EXPECT_EQ(system->extents()[0]->num_sectors(), 65536 / LP_SECTOR_SIZE); 62 EXPECT_EQ(system->extents()[0]->num_sectors(), 65536 / LP_SECTOR_SIZE);
63 // Test growing to a smaller size. 63 // Test resizing to a smaller size.
64 EXPECT_EQ(builder->GrowPartition(system, 0), true); 64 EXPECT_EQ(builder->ResizePartition(system, 0), true);
65 EXPECT_EQ(system->size(), 65536); 65 EXPECT_EQ(system->size(), 0);
66 EXPECT_EQ(system->extents().size(), 1); 66 EXPECT_EQ(system->extents().size(), 0);
67 EXPECT_EQ(system->extents()[0]->num_sectors(), 65536 / LP_SECTOR_SIZE); 67 // Test resizing to a greater size.
68 // Test shrinking to a greater size. 68 builder->ResizePartition(system, 131072);
69 builder->ShrinkPartition(system, 131072); 69 EXPECT_EQ(system->size(), 131072);
70 EXPECT_EQ(system->size(), 65536);
71 EXPECT_EQ(system->extents().size(), 1); 70 EXPECT_EQ(system->extents().size(), 1);
72 EXPECT_EQ(system->extents()[0]->num_sectors(), 65536 / LP_SECTOR_SIZE); 71 EXPECT_EQ(system->extents()[0]->num_sectors(), 131072 / LP_SECTOR_SIZE);
73 72
74 // Test shrinking within the same extent. 73 // Test shrinking within the same extent.
75 builder->ShrinkPartition(system, 32768); 74 builder->ResizePartition(system, 32768);
76 EXPECT_EQ(system->size(), 32768); 75 EXPECT_EQ(system->size(), 32768);
77 EXPECT_EQ(system->extents().size(), 1); 76 EXPECT_EQ(system->extents().size(), 1);
78 extent = system->extents()[0]->AsLinearExtent(); 77 extent = system->extents()[0]->AsLinearExtent();
@@ -81,7 +80,7 @@ TEST(liblp, ResizePartition) {
81 EXPECT_EQ(extent->physical_sector(), 12); 80 EXPECT_EQ(extent->physical_sector(), 12);
82 81
83 // Test shrinking to 0. 82 // Test shrinking to 0.
84 builder->ShrinkPartition(system, 0); 83 builder->ResizePartition(system, 0);
85 EXPECT_EQ(system->size(), 0); 84 EXPECT_EQ(system->size(), 0);
86 EXPECT_EQ(system->extents().size(), 0); 85 EXPECT_EQ(system->extents().size(), 0);
87} 86}
@@ -92,11 +91,11 @@ TEST(liblp, PartitionAlignment) {
92 // Test that we align up to one sector. 91 // Test that we align up to one sector.
93 Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY); 92 Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
94 ASSERT_NE(system, nullptr); 93 ASSERT_NE(system, nullptr);
95 EXPECT_EQ(builder->GrowPartition(system, 10000), true); 94 EXPECT_EQ(builder->ResizePartition(system, 10000), true);
96 EXPECT_EQ(system->size(), 10240); 95 EXPECT_EQ(system->size(), 10240);
97 EXPECT_EQ(system->extents().size(), 1); 96 EXPECT_EQ(system->extents().size(), 1);
98 97
99 builder->ShrinkPartition(system, 9000); 98 builder->ResizePartition(system, 9000);
100 EXPECT_EQ(system->size(), 9216); 99 EXPECT_EQ(system->size(), 9216);
101 EXPECT_EQ(system->extents().size(), 1); 100 EXPECT_EQ(system->extents().size(), 1);
102} 101}
@@ -174,8 +173,8 @@ TEST(liblp, InternalPartitionAlignment) {
174 173
175 // Add a bunch of small extents to each, interleaving. 174 // Add a bunch of small extents to each, interleaving.
176 for (size_t i = 0; i < 10; i++) { 175 for (size_t i = 0; i < 10; i++) {
177 ASSERT_TRUE(builder->GrowPartition(a, a->size() + 4096)); 176 ASSERT_TRUE(builder->ResizePartition(a, a->size() + 4096));
178 ASSERT_TRUE(builder->GrowPartition(b, b->size() + 4096)); 177 ASSERT_TRUE(builder->ResizePartition(b, b->size() + 4096));
179 } 178 }
180 EXPECT_EQ(a->size(), 40960); 179 EXPECT_EQ(a->size(), 40960);
181 EXPECT_EQ(b->size(), 40960); 180 EXPECT_EQ(b->size(), 40960);
@@ -203,9 +202,9 @@ TEST(liblp, UseAllDiskSpace) {
203 202
204 Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY); 203 Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
205 ASSERT_NE(system, nullptr); 204 ASSERT_NE(system, nullptr);
206 EXPECT_EQ(builder->GrowPartition(system, 1036288), true); 205 EXPECT_EQ(builder->ResizePartition(system, 1036288), true);
207 EXPECT_EQ(system->size(), 1036288); 206 EXPECT_EQ(system->size(), 1036288);
208 EXPECT_EQ(builder->GrowPartition(system, 1036289), false); 207 EXPECT_EQ(builder->ResizePartition(system, 1036289), false);
209} 208}
210 209
211TEST(liblp, BuildComplex) { 210TEST(liblp, BuildComplex) {
@@ -215,9 +214,9 @@ TEST(liblp, BuildComplex) {
215 Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY); 214 Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY);
216 ASSERT_NE(system, nullptr); 215 ASSERT_NE(system, nullptr);
217 ASSERT_NE(vendor, nullptr); 216 ASSERT_NE(vendor, nullptr);
218 EXPECT_EQ(builder->GrowPartition(system, 65536), true); 217 EXPECT_EQ(builder->ResizePartition(system, 65536), true);
219 EXPECT_EQ(builder->GrowPartition(vendor, 32768), true); 218 EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
220 EXPECT_EQ(builder->GrowPartition(system, 98304), true); 219 EXPECT_EQ(builder->ResizePartition(system, 98304), true);
221 EXPECT_EQ(system->size(), 98304); 220 EXPECT_EQ(system->size(), 98304);
222 EXPECT_EQ(vendor->size(), 32768); 221 EXPECT_EQ(vendor->size(), 32768);
223 222
@@ -268,9 +267,9 @@ TEST(liblp, BuilderExport) {
268 Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY); 267 Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY);
269 ASSERT_NE(system, nullptr); 268 ASSERT_NE(system, nullptr);
270 ASSERT_NE(vendor, nullptr); 269 ASSERT_NE(vendor, nullptr);
271 EXPECT_EQ(builder->GrowPartition(system, 65536), true); 270 EXPECT_EQ(builder->ResizePartition(system, 65536), true);
272 EXPECT_EQ(builder->GrowPartition(vendor, 32768), true); 271 EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
273 EXPECT_EQ(builder->GrowPartition(system, 98304), true); 272 EXPECT_EQ(builder->ResizePartition(system, 98304), true);
274 273
275 unique_ptr<LpMetadata> exported = builder->Export(); 274 unique_ptr<LpMetadata> exported = builder->Export();
276 EXPECT_NE(exported, nullptr); 275 EXPECT_NE(exported, nullptr);
@@ -323,9 +322,9 @@ TEST(liblp, BuilderImport) {
323 Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY); 322 Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY);
324 ASSERT_NE(system, nullptr); 323 ASSERT_NE(system, nullptr);
325 ASSERT_NE(vendor, nullptr); 324 ASSERT_NE(vendor, nullptr);
326 EXPECT_EQ(builder->GrowPartition(system, 65536), true); 325 EXPECT_EQ(builder->ResizePartition(system, 65536), true);
327 EXPECT_EQ(builder->GrowPartition(vendor, 32768), true); 326 EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
328 EXPECT_EQ(builder->GrowPartition(system, 98304), true); 327 EXPECT_EQ(builder->ResizePartition(system, 98304), true);
329 328
330 unique_ptr<LpMetadata> exported = builder->Export(); 329 unique_ptr<LpMetadata> exported = builder->Export();
331 ASSERT_NE(exported, nullptr); 330 ASSERT_NE(exported, nullptr);
diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h
index 8bde3132c..0f96e3a60 100644
--- a/fs_mgr/liblp/include/liblp/builder.h
+++ b/fs_mgr/liblp/include/liblp/builder.h
@@ -162,29 +162,17 @@ class MetadataBuilder {
162 // Find a partition by name. If no partition is found, nullptr is returned. 162 // Find a partition by name. If no partition is found, nullptr is returned.
163 Partition* FindPartition(const std::string& name); 163 Partition* FindPartition(const std::string& name);
164 164
165 // Grow a partition to the requested size. If the partition's size is already 165 // Grow or shrink a partition to the requested size. This size will be
166 // greater or equal to the requested size, this will return true and the 166 // rounded UP to the nearest block (512 bytes).
167 // partition table will not be changed. Otherwise, a greedy algorithm is
168 // used to find free gaps in the partition table and allocate them for this
169 // partition. If not enough space can be allocated, false is returned, and
170 // the parition table will not be modified.
171 // 167 //
172 // The size will be rounded UP to the nearest sector. 168 // When growing a partition, a greedy algorithm is used to find free gaps
169 // in the partition table and allocate them. If not enough space can be
170 // allocated, false is returned, and the parition table will not be
171 // modified.
173 // 172 //
174 // Note, this is an in-memory operation, and it does not alter the 173 // Note, this is an in-memory operation, and it does not alter the
175 // underlying filesystem or contents of the partition on disk. 174 // underlying filesystem or contents of the partition on disk.
176 bool GrowPartition(Partition* partition, uint64_t requested_size); 175 bool ResizePartition(Partition* partition, uint64_t requested_size);
177
178 // Shrink a partition to the requested size. If the partition is already
179 // smaller than the given size, this will return and the partition table
180 // will not be changed. Otherwise, extents will be removed and/or shrunk
181 // from the end of the partition until it is the requested size.
182 //
183 // The size will be rounded UP to the nearest sector.
184 //
185 // Note, this is an in-memory operation, and it does not alter the
186 // underlying filesystem or contents of the partition on disk.
187 void ShrinkPartition(Partition* partition, uint64_t requested_size);
188 176
189 // Amount of space that can be allocated to logical partitions. 177 // Amount of space that can be allocated to logical partitions.
190 uint64_t AllocatableSpace() const; 178 uint64_t AllocatableSpace() const;
@@ -198,7 +186,8 @@ class MetadataBuilder {
198 MetadataBuilder(); 186 MetadataBuilder();
199 bool Init(const BlockDeviceInfo& info, uint32_t metadata_max_size, uint32_t metadata_slot_count); 187 bool Init(const BlockDeviceInfo& info, uint32_t metadata_max_size, uint32_t metadata_slot_count);
200 bool Init(const LpMetadata& metadata); 188 bool Init(const LpMetadata& metadata);
201 189 bool GrowPartition(Partition* partition, uint64_t aligned_size);
190 void ShrinkPartition(Partition* partition, uint64_t aligned_size);
202 uint64_t AlignSector(uint64_t sector); 191 uint64_t AlignSector(uint64_t sector);
203 192
204 LpMetadataGeometry geometry_; 193 LpMetadataGeometry geometry_;
diff --git a/fs_mgr/liblp/io_test.cpp b/fs_mgr/liblp/io_test.cpp
index bbbedc761..638f4b310 100644
--- a/fs_mgr/liblp/io_test.cpp
+++ b/fs_mgr/liblp/io_test.cpp
@@ -85,7 +85,7 @@ static bool AddDefaultPartitions(MetadataBuilder* builder) {
85 if (!system) { 85 if (!system) {
86 return false; 86 return false;
87 } 87 }
88 return builder->GrowPartition(system, 24 * 1024); 88 return builder->ResizePartition(system, 24 * 1024);
89} 89}
90 90
91// Create a temporary disk and flash it with the default partition setup. 91// Create a temporary disk and flash it with the default partition setup.
@@ -345,7 +345,7 @@ TEST(liblp, TooManyPartitions) {
345 ASSERT_NE(partition, nullptr); 345 ASSERT_NE(partition, nullptr);
346 // Add one extent to any partition to fill up more space - we're at 508 346 // Add one extent to any partition to fill up more space - we're at 508
347 // bytes after this, out of 512. 347 // bytes after this, out of 512.
348 ASSERT_TRUE(builder->GrowPartition(partition, 1024)); 348 ASSERT_TRUE(builder->ResizePartition(partition, 1024));
349 349
350 unique_ptr<LpMetadata> exported = builder->Export(); 350 unique_ptr<LpMetadata> exported = builder->Export();
351 ASSERT_NE(exported, nullptr); 351 ASSERT_NE(exported, nullptr);