diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/test_v3.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/test_v3.cpp index 8cf46f42e..de602138d 100644 --- a/fs_mgr/libsnapshot/libsnapshot_cow/test_v3.cpp +++ b/fs_mgr/libsnapshot/libsnapshot_cow/test_v3.cpp @@ -72,6 +72,7 @@ TEST_F(CowTestV3, CowHeaderV2Test) { TEST_F(CowTestV3, Header) { CowOptions options; + options.op_count_max = 15; auto writer = CreateCowWriter(3, options, GetCowFd()); ASSERT_TRUE(writer->Finalize()); diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/writer_v3.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/writer_v3.cpp index 0e131970e..051b2fb8a 100644 --- a/fs_mgr/libsnapshot/libsnapshot_cow/writer_v3.cpp +++ b/fs_mgr/libsnapshot/libsnapshot_cow/writer_v3.cpp @@ -129,6 +129,18 @@ bool CowWriterV3::ParseOptions() { header_.compression_algorithm = *algorithm; header_.op_count_max = options_.op_count_max; + if (!IsEstimating() && header_.op_count_max == 0) { + if (!options_.max_blocks.has_value()) { + LOG(ERROR) << "can't size op buffer size since op_count_max is 0 and max_blocks is not " + "set."; + return false; + } + LOG(INFO) << "op count max is read in as 0. Setting to " + "num blocks in partition " + << options_.max_blocks.value(); + header_.op_count_max = options_.max_blocks.value(); + } + if (parts.size() > 1) { if (!android::base::ParseUint(parts[1], &compression_.compression_level)) { LOG(ERROR) << "failed to parse compression level invalid type: " << parts[1]; diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp index c12a9e223..9ce00e5f8 100644 --- a/fs_mgr/libsnapshot/snapshot.cpp +++ b/fs_mgr/libsnapshot/snapshot.cpp @@ -1142,8 +1142,8 @@ auto SnapshotManager::CheckMergeState(const std::function& before_cancel return result; } -auto SnapshotManager::CheckMergeState(LockedFile* lock, const std::function& before_cancel) - -> MergeResult { +auto SnapshotManager::CheckMergeState(LockedFile* lock, + const std::function& before_cancel) -> MergeResult { SnapshotUpdateStatus update_status = ReadSnapshotUpdateStatus(lock); switch (update_status.state()) { case UpdateState::None: @@ -1218,8 +1218,8 @@ auto SnapshotManager::CheckMergeState(LockedFile* lock, const std::function std::unique_ptr { +auto SnapshotManager::OpenFile(const std::string& file, + int lock_flags) -> std::unique_ptr { unique_fd fd(open(file.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW)); if (fd < 0) { PLOG(ERROR) << "Open failed: " << file; @@ -3558,6 +3558,7 @@ Return SnapshotManager::InitializeUpdateSnapshots( options.compression = it->second.compression_algorithm(); if (cow_version >= 3) { options.op_count_max = it->second.estimated_ops_buffer_size(); + options.max_blocks = {it->second.device_size() / options.block_size}; } auto writer = CreateCowWriter(cow_version, options, std::move(fd)); @@ -4343,8 +4344,7 @@ bool SnapshotManager::DeleteDeviceIfExists(const std::string& name, } } - LOG(ERROR) << "Device-mapper device " << name << "(" << full_path << ")" - << " still in use." + LOG(ERROR) << "Device-mapper device " << name << "(" << full_path << ")" << " still in use." << " Probably a file descriptor was leaked or held open, or a loop device is" << " attached."; return false;