fs_mgr: Add a helper for creating one-off dynamic partitions.

This will be used by gsid to invoke mkfs.ext4 on the userdata_gsi
partition. Since the extents are not located on the super partition, we
need a helper method that takes in an LpMetadata.

Bug: 121210348
Test: manual test
Change-Id: I00467ace8a745fb0c0d130babfda1a2d5d97c208
diff --git a/fs_mgr/fs_mgr_dm_linear.cpp b/fs_mgr/fs_mgr_dm_linear.cpp
index 3f075ef..45cbff3 100644
--- a/fs_mgr/fs_mgr_dm_linear.cpp
+++ b/fs_mgr/fs_mgr_dm_linear.cpp
@@ -168,6 +168,19 @@
     return true;
 }
 
+bool CreateLogicalPartition(const std::string& block_device, const LpMetadata& metadata,
+                            const std::string& partition_name, bool force_writable,
+                            const std::chrono::milliseconds& timeout_ms, std::string* path) {
+    for (const auto& partition : metadata.partitions) {
+        if (GetPartitionName(partition) == partition_name) {
+            return CreateLogicalPartition(metadata, partition, force_writable, timeout_ms,
+                                          block_device, path);
+        }
+    }
+    LERROR << "Could not find any partition with name: " << partition_name;
+    return false;
+}
+
 bool CreateLogicalPartition(const std::string& block_device, uint32_t metadata_slot,
                             const std::string& partition_name, bool force_writable,
                             const std::chrono::milliseconds& timeout_ms, std::string* path) {
@@ -176,14 +189,8 @@
         LOG(ERROR) << "Could not read partition table.";
         return true;
     }
-    for (const auto& partition : metadata->partitions) {
-        if (GetPartitionName(partition) == partition_name) {
-            return CreateLogicalPartition(*metadata.get(), partition, force_writable, timeout_ms,
-                                          block_device, path);
-        }
-    }
-    LERROR << "Could not find any partition with name: " << partition_name;
-    return false;
+    return CreateLogicalPartition(block_device, *metadata.get(), partition_name, force_writable,
+                                  timeout_ms, path);
 }
 
 bool DestroyLogicalPartition(const std::string& name, const std::chrono::milliseconds& timeout_ms) {
diff --git a/fs_mgr/include/fs_mgr_dm_linear.h b/fs_mgr/include/fs_mgr_dm_linear.h
index f065071..f33fc02 100644
--- a/fs_mgr/include/fs_mgr_dm_linear.h
+++ b/fs_mgr/include/fs_mgr_dm_linear.h
@@ -60,6 +60,12 @@
                             const std::string& partition_name, bool force_writable,
                             const std::chrono::milliseconds& timeout_ms, std::string* path);
 
+// Same as above, but with a given metadata object. Care should be taken that
+// the metadata represents a valid partition layout.
+bool CreateLogicalPartition(const std::string& block_device, const LpMetadata& metadata,
+                            const std::string& partition_name, bool force_writable,
+                            const std::chrono::milliseconds& timeout_ms, std::string* path);
+
 // Destroy the block device for a logical partition, by name. If |timeout_ms|
 // is non-zero, then this will block until the device path has been unlinked.
 bool DestroyLogicalPartition(const std::string& name, const std::chrono::milliseconds& timeout_ms);