liblp: Don't store BlockDeviceInfo separately in MetadataBuilder.
There's no reason to do this, since the fields are already in
LpMetadataGeometry. Removing this also simplifies multiple-block-device
support.
Bug: 116802789
Test: liblp_test gtest
Change-Id: Ib244a98fdd9d36c94a2dffd81bef68a1d5644ab9
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index 765ed8d..743a3fe 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -150,7 +150,7 @@
}
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 @@
}
}
}
-
- 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 @@
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,21 +262,21 @@
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(total_reserved, device_info_.alignment, device_info_.alignment_offset);
+ 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 / 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
@@ -297,7 +292,7 @@
// 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;
@@ -308,9 +303,9 @@
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)) {
@@ -461,7 +456,7 @@
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);
@@ -579,32 +574,44 @@
// 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) {
diff --git a/fs_mgr/liblp/builder_test.cpp b/fs_mgr/liblp/builder_test.cpp
index 34f9dd3..ffa7d3b 100644
--- a/fs_mgr/liblp/builder_test.cpp
+++ b/fs_mgr/liblp/builder_test.cpp
@@ -435,22 +435,37 @@
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) {
diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h
index a6044d0..8dbba84 100644
--- a/fs_mgr/liblp/include/liblp/builder.h
+++ b/fs_mgr/liblp/include/liblp/builder.h
@@ -215,10 +215,8 @@
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 @@
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