Loading adb/client/adb_client.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -259,7 +259,7 @@ static bool __adb_check_server_version(std::string* error) { if (fd >= 0) { std::string version_string; if (!ReadProtocolString(fd, &version_string, error)) { return -1; return false; } ReadOrderlyShutdown(fd); Loading adb/daemon/usb.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -115,7 +115,7 @@ struct TransferId { }; struct IoBlock { bool pending; bool pending = false; struct iocb control; std::shared_ptr<Block> payload; Loading fs_mgr/liblp/builder.cpp +75 −15 Original line number Diff line number Diff line Loading @@ -591,11 +591,25 @@ bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t aligned_size) free_regions = PrioritizeSecondHalfOfSuper(free_regions); } // Find gaps that we can use for new extents. Note we store new extents in a // temporary vector, and only commit them if we are guaranteed enough free // space. // Note we store new extents in a temporary vector, and only commit them // if we are guaranteed enough free space. std::vector<std::unique_ptr<LinearExtent>> new_extents; // If the last extent in the partition has a size < alignment, then the // difference is unallocatable due to being misaligned. We peek for that // case here to avoid wasting space. if (auto extent = ExtendFinalExtent(partition, free_regions, sectors_needed)) { sectors_needed -= extent->num_sectors(); new_extents.emplace_back(std::move(extent)); } for (auto& region : free_regions) { // Note: this comes first, since we may enter the loop not needing any // more sectors. if (!sectors_needed) { break; } if (region.length() % sectors_per_block != 0) { // This should never happen, because it would imply that we // once allocated an extent that was not a multiple of the Loading @@ -613,22 +627,10 @@ bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t aligned_size) } uint64_t sectors = std::min(sectors_needed, region.length()); if (sectors < region.length()) { const auto& block_device = block_devices_[region.device_index]; if (block_device.alignment) { const uint64_t alignment = block_device.alignment / LP_SECTOR_SIZE; sectors = AlignTo(sectors, alignment); sectors = std::min(sectors, region.length()); } } CHECK(sectors % sectors_per_block == 0); auto extent = std::make_unique<LinearExtent>(sectors, region.device_index, region.start); new_extents.push_back(std::move(extent)); if (sectors >= sectors_needed) { sectors_needed = 0; break; } sectors_needed -= sectors; } if (sectors_needed) { Loading Loading @@ -677,6 +679,64 @@ std::vector<MetadataBuilder::Interval> MetadataBuilder::PrioritizeSecondHalfOfSu return second_half; } std::unique_ptr<LinearExtent> MetadataBuilder::ExtendFinalExtent( Partition* partition, const std::vector<Interval>& free_list, uint64_t sectors_needed) const { if (partition->extents().empty()) { return nullptr; } LinearExtent* extent = partition->extents().back()->AsLinearExtent(); if (!extent) { return nullptr; } // If the sector ends where the next aligned chunk begins, then there's // no missing gap to try and allocate. const auto& block_device = block_devices_[extent->device_index()]; uint64_t next_aligned_sector = AlignSector(block_device, extent->end_sector()); if (extent->end_sector() == next_aligned_sector) { return nullptr; } uint64_t num_sectors = std::min(next_aligned_sector - extent->end_sector(), sectors_needed); auto new_extent = std::make_unique<LinearExtent>(num_sectors, extent->device_index(), extent->end_sector()); if (IsAnyRegionAllocated(*new_extent.get()) || IsAnyRegionCovered(free_list, *new_extent.get())) { LERROR << "Misaligned region " << new_extent->physical_sector() << ".." << new_extent->end_sector() << " was allocated or marked allocatable."; return nullptr; } return new_extent; } bool MetadataBuilder::IsAnyRegionCovered(const std::vector<Interval>& regions, const LinearExtent& candidate) const { for (const auto& region : regions) { if (region.device_index == candidate.device_index() && (candidate.OwnsSector(region.start) || candidate.OwnsSector(region.end))) { return true; } } return false; } bool MetadataBuilder::IsAnyRegionAllocated(const LinearExtent& candidate) const { for (const auto& partition : partitions_) { for (const auto& extent : partition->extents()) { LinearExtent* linear = extent->AsLinearExtent(); if (!linear || linear->device_index() != candidate.device_index()) { continue; } if (linear->OwnsSector(candidate.physical_sector()) || linear->OwnsSector(candidate.end_sector() - 1)) { return true; } } } return false; } void MetadataBuilder::ShrinkPartition(Partition* partition, uint64_t aligned_size) { partition->ShrinkTo(aligned_size); } Loading fs_mgr/liblp/builder_test.cpp +7 −7 Original line number Diff line number Diff line Loading @@ -209,8 +209,8 @@ TEST_F(BuilderTest, InternalPartitionAlignment) { ASSERT_TRUE(builder->ResizePartition(a, a->size() + 4096)); ASSERT_TRUE(builder->ResizePartition(b, b->size() + 4096)); } EXPECT_EQ(a->size(), 7864320); EXPECT_EQ(b->size(), 7864320); EXPECT_EQ(a->size(), 40960); EXPECT_EQ(b->size(), 40960); unique_ptr<LpMetadata> exported = builder->Export(); ASSERT_NE(exported, nullptr); Loading @@ -218,7 +218,7 @@ TEST_F(BuilderTest, InternalPartitionAlignment) { // Check that each starting sector is aligned. for (const auto& extent : exported->extents) { ASSERT_EQ(extent.target_type, LP_TARGET_TYPE_LINEAR); EXPECT_EQ(extent.num_sectors, 1536); EXPECT_EQ(extent.num_sectors, 80); uint64_t lba = extent.target_data * LP_SECTOR_SIZE; uint64_t aligned_lba = AlignTo(lba, device_info.alignment, device_info.alignment_offset); Loading @@ -226,7 +226,7 @@ TEST_F(BuilderTest, InternalPartitionAlignment) { } // Sanity check one extent. EXPECT_EQ(exported->extents.back().target_data, 30656); EXPECT_EQ(exported->extents.back().target_data, 3008); } TEST_F(BuilderTest, UseAllDiskSpace) { Loading Loading @@ -698,7 +698,7 @@ TEST_F(BuilderTest, MultipleBlockDevices) { EXPECT_EQ(metadata->extents[1].target_type, LP_TARGET_TYPE_LINEAR); EXPECT_EQ(metadata->extents[1].target_data, 1472); EXPECT_EQ(metadata->extents[1].target_source, 1); EXPECT_EQ(metadata->extents[2].num_sectors, 129600); EXPECT_EQ(metadata->extents[2].num_sectors, 129088); EXPECT_EQ(metadata->extents[2].target_type, LP_TARGET_TYPE_LINEAR); EXPECT_EQ(metadata->extents[2].target_data, 1472); EXPECT_EQ(metadata->extents[2].target_source, 2); Loading Loading @@ -805,7 +805,7 @@ TEST_F(BuilderTest, ABExtents) { EXPECT_EQ(exported->extents[0].target_data, 10487808); EXPECT_EQ(exported->extents[0].num_sectors, 10483712); EXPECT_EQ(exported->extents[1].target_data, 6292992); EXPECT_EQ(exported->extents[1].num_sectors, 2099712); EXPECT_EQ(exported->extents[1].num_sectors, 2099200); EXPECT_EQ(exported->extents[2].target_data, 1536); EXPECT_EQ(exported->extents[2].num_sectors, 6291456); } Loading @@ -821,7 +821,7 @@ TEST_F(BuilderTest, PartialExtents) { ASSERT_NE(vendor, nullptr); ASSERT_TRUE(builder->ResizePartition(system, device_info.alignment + 4096)); ASSERT_TRUE(builder->ResizePartition(vendor, device_info.alignment)); ASSERT_EQ(system->size(), device_info.alignment * 2); ASSERT_EQ(system->size(), device_info.alignment + 4096); ASSERT_EQ(vendor->size(), device_info.alignment); ASSERT_TRUE(builder->ResizePartition(system, device_info.alignment * 2)); Loading fs_mgr/liblp/include/liblp/builder.h +10 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,10 @@ class LinearExtent final : public Extent { uint64_t end_sector() const { return physical_sector_ + num_sectors_; } uint32_t device_index() const { return device_index_; } bool OwnsSector(uint64_t sector) const { return sector >= physical_sector_ && sector < end_sector(); } private: uint32_t device_index_; uint64_t physical_sector_; Loading Loading @@ -322,9 +326,15 @@ class MetadataBuilder { } }; std::vector<Interval> GetFreeRegions() const; bool IsAnyRegionCovered(const std::vector<Interval>& regions, const LinearExtent& candidate) const; bool IsAnyRegionAllocated(const LinearExtent& candidate) const; void ExtentsToFreeList(const std::vector<Interval>& extents, std::vector<Interval>* free_regions) const; std::vector<Interval> PrioritizeSecondHalfOfSuper(const std::vector<Interval>& free_list); std::unique_ptr<LinearExtent> ExtendFinalExtent(Partition* partition, const std::vector<Interval>& free_list, uint64_t sectors_needed) const; static bool sABOverrideValue; static bool sABOverrideSet; Loading Loading
adb/client/adb_client.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -259,7 +259,7 @@ static bool __adb_check_server_version(std::string* error) { if (fd >= 0) { std::string version_string; if (!ReadProtocolString(fd, &version_string, error)) { return -1; return false; } ReadOrderlyShutdown(fd); Loading
adb/daemon/usb.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -115,7 +115,7 @@ struct TransferId { }; struct IoBlock { bool pending; bool pending = false; struct iocb control; std::shared_ptr<Block> payload; Loading
fs_mgr/liblp/builder.cpp +75 −15 Original line number Diff line number Diff line Loading @@ -591,11 +591,25 @@ bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t aligned_size) free_regions = PrioritizeSecondHalfOfSuper(free_regions); } // Find gaps that we can use for new extents. Note we store new extents in a // temporary vector, and only commit them if we are guaranteed enough free // space. // Note we store new extents in a temporary vector, and only commit them // if we are guaranteed enough free space. std::vector<std::unique_ptr<LinearExtent>> new_extents; // If the last extent in the partition has a size < alignment, then the // difference is unallocatable due to being misaligned. We peek for that // case here to avoid wasting space. if (auto extent = ExtendFinalExtent(partition, free_regions, sectors_needed)) { sectors_needed -= extent->num_sectors(); new_extents.emplace_back(std::move(extent)); } for (auto& region : free_regions) { // Note: this comes first, since we may enter the loop not needing any // more sectors. if (!sectors_needed) { break; } if (region.length() % sectors_per_block != 0) { // This should never happen, because it would imply that we // once allocated an extent that was not a multiple of the Loading @@ -613,22 +627,10 @@ bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t aligned_size) } uint64_t sectors = std::min(sectors_needed, region.length()); if (sectors < region.length()) { const auto& block_device = block_devices_[region.device_index]; if (block_device.alignment) { const uint64_t alignment = block_device.alignment / LP_SECTOR_SIZE; sectors = AlignTo(sectors, alignment); sectors = std::min(sectors, region.length()); } } CHECK(sectors % sectors_per_block == 0); auto extent = std::make_unique<LinearExtent>(sectors, region.device_index, region.start); new_extents.push_back(std::move(extent)); if (sectors >= sectors_needed) { sectors_needed = 0; break; } sectors_needed -= sectors; } if (sectors_needed) { Loading Loading @@ -677,6 +679,64 @@ std::vector<MetadataBuilder::Interval> MetadataBuilder::PrioritizeSecondHalfOfSu return second_half; } std::unique_ptr<LinearExtent> MetadataBuilder::ExtendFinalExtent( Partition* partition, const std::vector<Interval>& free_list, uint64_t sectors_needed) const { if (partition->extents().empty()) { return nullptr; } LinearExtent* extent = partition->extents().back()->AsLinearExtent(); if (!extent) { return nullptr; } // If the sector ends where the next aligned chunk begins, then there's // no missing gap to try and allocate. const auto& block_device = block_devices_[extent->device_index()]; uint64_t next_aligned_sector = AlignSector(block_device, extent->end_sector()); if (extent->end_sector() == next_aligned_sector) { return nullptr; } uint64_t num_sectors = std::min(next_aligned_sector - extent->end_sector(), sectors_needed); auto new_extent = std::make_unique<LinearExtent>(num_sectors, extent->device_index(), extent->end_sector()); if (IsAnyRegionAllocated(*new_extent.get()) || IsAnyRegionCovered(free_list, *new_extent.get())) { LERROR << "Misaligned region " << new_extent->physical_sector() << ".." << new_extent->end_sector() << " was allocated or marked allocatable."; return nullptr; } return new_extent; } bool MetadataBuilder::IsAnyRegionCovered(const std::vector<Interval>& regions, const LinearExtent& candidate) const { for (const auto& region : regions) { if (region.device_index == candidate.device_index() && (candidate.OwnsSector(region.start) || candidate.OwnsSector(region.end))) { return true; } } return false; } bool MetadataBuilder::IsAnyRegionAllocated(const LinearExtent& candidate) const { for (const auto& partition : partitions_) { for (const auto& extent : partition->extents()) { LinearExtent* linear = extent->AsLinearExtent(); if (!linear || linear->device_index() != candidate.device_index()) { continue; } if (linear->OwnsSector(candidate.physical_sector()) || linear->OwnsSector(candidate.end_sector() - 1)) { return true; } } } return false; } void MetadataBuilder::ShrinkPartition(Partition* partition, uint64_t aligned_size) { partition->ShrinkTo(aligned_size); } Loading
fs_mgr/liblp/builder_test.cpp +7 −7 Original line number Diff line number Diff line Loading @@ -209,8 +209,8 @@ TEST_F(BuilderTest, InternalPartitionAlignment) { ASSERT_TRUE(builder->ResizePartition(a, a->size() + 4096)); ASSERT_TRUE(builder->ResizePartition(b, b->size() + 4096)); } EXPECT_EQ(a->size(), 7864320); EXPECT_EQ(b->size(), 7864320); EXPECT_EQ(a->size(), 40960); EXPECT_EQ(b->size(), 40960); unique_ptr<LpMetadata> exported = builder->Export(); ASSERT_NE(exported, nullptr); Loading @@ -218,7 +218,7 @@ TEST_F(BuilderTest, InternalPartitionAlignment) { // Check that each starting sector is aligned. for (const auto& extent : exported->extents) { ASSERT_EQ(extent.target_type, LP_TARGET_TYPE_LINEAR); EXPECT_EQ(extent.num_sectors, 1536); EXPECT_EQ(extent.num_sectors, 80); uint64_t lba = extent.target_data * LP_SECTOR_SIZE; uint64_t aligned_lba = AlignTo(lba, device_info.alignment, device_info.alignment_offset); Loading @@ -226,7 +226,7 @@ TEST_F(BuilderTest, InternalPartitionAlignment) { } // Sanity check one extent. EXPECT_EQ(exported->extents.back().target_data, 30656); EXPECT_EQ(exported->extents.back().target_data, 3008); } TEST_F(BuilderTest, UseAllDiskSpace) { Loading Loading @@ -698,7 +698,7 @@ TEST_F(BuilderTest, MultipleBlockDevices) { EXPECT_EQ(metadata->extents[1].target_type, LP_TARGET_TYPE_LINEAR); EXPECT_EQ(metadata->extents[1].target_data, 1472); EXPECT_EQ(metadata->extents[1].target_source, 1); EXPECT_EQ(metadata->extents[2].num_sectors, 129600); EXPECT_EQ(metadata->extents[2].num_sectors, 129088); EXPECT_EQ(metadata->extents[2].target_type, LP_TARGET_TYPE_LINEAR); EXPECT_EQ(metadata->extents[2].target_data, 1472); EXPECT_EQ(metadata->extents[2].target_source, 2); Loading Loading @@ -805,7 +805,7 @@ TEST_F(BuilderTest, ABExtents) { EXPECT_EQ(exported->extents[0].target_data, 10487808); EXPECT_EQ(exported->extents[0].num_sectors, 10483712); EXPECT_EQ(exported->extents[1].target_data, 6292992); EXPECT_EQ(exported->extents[1].num_sectors, 2099712); EXPECT_EQ(exported->extents[1].num_sectors, 2099200); EXPECT_EQ(exported->extents[2].target_data, 1536); EXPECT_EQ(exported->extents[2].num_sectors, 6291456); } Loading @@ -821,7 +821,7 @@ TEST_F(BuilderTest, PartialExtents) { ASSERT_NE(vendor, nullptr); ASSERT_TRUE(builder->ResizePartition(system, device_info.alignment + 4096)); ASSERT_TRUE(builder->ResizePartition(vendor, device_info.alignment)); ASSERT_EQ(system->size(), device_info.alignment * 2); ASSERT_EQ(system->size(), device_info.alignment + 4096); ASSERT_EQ(vendor->size(), device_info.alignment); ASSERT_TRUE(builder->ResizePartition(system, device_info.alignment * 2)); Loading
fs_mgr/liblp/include/liblp/builder.h +10 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,10 @@ class LinearExtent final : public Extent { uint64_t end_sector() const { return physical_sector_ + num_sectors_; } uint32_t device_index() const { return device_index_; } bool OwnsSector(uint64_t sector) const { return sector >= physical_sector_ && sector < end_sector(); } private: uint32_t device_index_; uint64_t physical_sector_; Loading Loading @@ -322,9 +326,15 @@ class MetadataBuilder { } }; std::vector<Interval> GetFreeRegions() const; bool IsAnyRegionCovered(const std::vector<Interval>& regions, const LinearExtent& candidate) const; bool IsAnyRegionAllocated(const LinearExtent& candidate) const; void ExtentsToFreeList(const std::vector<Interval>& extents, std::vector<Interval>* free_regions) const; std::vector<Interval> PrioritizeSecondHalfOfSuper(const std::vector<Interval>& free_list); std::unique_ptr<LinearExtent> ExtendFinalExtent(Partition* partition, const std::vector<Interval>& free_list, uint64_t sectors_needed) const; static bool sABOverrideValue; static bool sABOverrideSet; Loading