Loading fs_mgr/fs_mgr_overlayfs.cpp +60 −14 Original line number Diff line number Diff line Loading @@ -815,26 +815,72 @@ std::string fs_mgr_overlayfs_scratch_mount_type() { return "auto"; } std::string fs_mgr_overlayfs_scratch_device() { if (!scratch_device_cache.empty()) return scratch_device_cache; enum class ScratchStrategy { kNone, // DAP device, use logical partitions. kDynamicPartition, // Retrofit DAP device, use super_<other>. kSuperOther, // Pre-DAP device, uses the other slot. kSystemOther }; // Is this a multiple super device (retrofit)? static ScratchStrategy GetScratchStrategy(std::string* backing_device) { auto slot_number = fs_mgr_overlayfs_slot_number(); auto super_device = fs_mgr_overlayfs_super_device(slot_number); auto path = fs_mgr_overlayfs_super_device(slot_number == 0); if (super_device == path) { // Create from within single super device; auto& dm = DeviceMapper::Instance(); const auto partition_name = android::base::Basename(kScratchMountPoint); if (!dm.GetDmDevicePathByName(partition_name, &path)) { // non-DAP A/B device? if (fs_mgr_access(super_device)) return ""; if (super_device != path) { // Note: we do not check access() here, since in first-stage init we // wouldn't have registed by-name symlinks for the device as it's // normally not needed. The access checks elsewhere in this function // are safe because system/super are always required. *backing_device = path; return ScratchStrategy::kSuperOther; } if (fs_mgr_access(super_device)) { *backing_device = super_device; return ScratchStrategy::kDynamicPartition; } auto other_slot = fs_mgr_get_other_slot_suffix(); if (other_slot.empty()) return ""; if (!other_slot.empty()) { path = kPhysicalDevice + "system" + other_slot; if (fs_mgr_access(path)) { *backing_device = path; return ScratchStrategy::kSystemOther; } } return ScratchStrategy::kNone; } // Return the scratch device if it exists. static std::string GetScratchDevice() { std::string device; ScratchStrategy strategy = GetScratchStrategy(&device); switch (strategy) { case ScratchStrategy::kSuperOther: case ScratchStrategy::kSystemOther: return device; case ScratchStrategy::kDynamicPartition: { auto& dm = DeviceMapper::Instance(); auto partition_name = android::base::Basename(kScratchMountPoint); if (dm.GetState(partition_name) != DmDeviceState::INVALID && dm.GetDmDevicePathByName(partition_name, &device)) { return device; } return ""; } default: return ""; } return scratch_device_cache = path; } std::string fs_mgr_overlayfs_scratch_device() { if (!scratch_device_cache.empty()) return scratch_device_cache; scratch_device_cache = GetScratchDevice(); return scratch_device_cache; } bool fs_mgr_overlayfs_make_scratch(const std::string& scratch_device, const std::string& mnt_type) { Loading Loading
fs_mgr/fs_mgr_overlayfs.cpp +60 −14 Original line number Diff line number Diff line Loading @@ -815,26 +815,72 @@ std::string fs_mgr_overlayfs_scratch_mount_type() { return "auto"; } std::string fs_mgr_overlayfs_scratch_device() { if (!scratch_device_cache.empty()) return scratch_device_cache; enum class ScratchStrategy { kNone, // DAP device, use logical partitions. kDynamicPartition, // Retrofit DAP device, use super_<other>. kSuperOther, // Pre-DAP device, uses the other slot. kSystemOther }; // Is this a multiple super device (retrofit)? static ScratchStrategy GetScratchStrategy(std::string* backing_device) { auto slot_number = fs_mgr_overlayfs_slot_number(); auto super_device = fs_mgr_overlayfs_super_device(slot_number); auto path = fs_mgr_overlayfs_super_device(slot_number == 0); if (super_device == path) { // Create from within single super device; auto& dm = DeviceMapper::Instance(); const auto partition_name = android::base::Basename(kScratchMountPoint); if (!dm.GetDmDevicePathByName(partition_name, &path)) { // non-DAP A/B device? if (fs_mgr_access(super_device)) return ""; if (super_device != path) { // Note: we do not check access() here, since in first-stage init we // wouldn't have registed by-name symlinks for the device as it's // normally not needed. The access checks elsewhere in this function // are safe because system/super are always required. *backing_device = path; return ScratchStrategy::kSuperOther; } if (fs_mgr_access(super_device)) { *backing_device = super_device; return ScratchStrategy::kDynamicPartition; } auto other_slot = fs_mgr_get_other_slot_suffix(); if (other_slot.empty()) return ""; if (!other_slot.empty()) { path = kPhysicalDevice + "system" + other_slot; if (fs_mgr_access(path)) { *backing_device = path; return ScratchStrategy::kSystemOther; } } return ScratchStrategy::kNone; } // Return the scratch device if it exists. static std::string GetScratchDevice() { std::string device; ScratchStrategy strategy = GetScratchStrategy(&device); switch (strategy) { case ScratchStrategy::kSuperOther: case ScratchStrategy::kSystemOther: return device; case ScratchStrategy::kDynamicPartition: { auto& dm = DeviceMapper::Instance(); auto partition_name = android::base::Basename(kScratchMountPoint); if (dm.GetState(partition_name) != DmDeviceState::INVALID && dm.GetDmDevicePathByName(partition_name, &device)) { return device; } return ""; } default: return ""; } return scratch_device_cache = path; } std::string fs_mgr_overlayfs_scratch_device() { if (!scratch_device_cache.empty()) return scratch_device_cache; scratch_device_cache = GetScratchDevice(); return scratch_device_cache; } bool fs_mgr_overlayfs_make_scratch(const std::string& scratch_device, const std::string& mnt_type) { Loading