Revert "libsnapshot: Add Parser base class"
Revert submission 2781730
Reason for revert: It breaks build
Reverted changes: /q/submissionid:2781730
Bug: 308868619
Change-Id: I255263d14a1ced57b80efd373dd22eb22bb6efc1
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
index 4cbcab1..debaf36 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
@@ -185,6 +185,7 @@
std::shared_ptr<std::unordered_map<uint64_t, uint64_t>> data_loc_;
ReaderFlags reader_flag_;
bool is_merge_{};
+ uint8_t compression_type_ = kCowCompressNone;
};
// Though this function takes in a CowHeaderV3, the struct could be populated as a v1/v2 CowHeader.
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp
index 6f1854d..3b84c95 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp
@@ -28,6 +28,7 @@
#include <zlib.h>
#include "cow_decompress.h"
+#include "libsnapshot/cow_format.h"
#include "parser_v2.h"
namespace android {
@@ -84,6 +85,7 @@
cow->data_loc_ = data_loc_;
cow->block_pos_index_ = block_pos_index_;
cow->is_merge_ = is_merge_;
+ cow->compression_type_ = compression_type_;
return cow;
}
@@ -102,14 +104,11 @@
PLOG(ERROR) << "lseek header failed";
return false;
}
-
- CHECK_GE(header_.prefix.header_size, sizeof(CowHeader));
- CHECK_LE(header_.prefix.header_size, sizeof(header_));
-
- if (!android::base::ReadFully(fd_, &header_, header_.prefix.header_size)) {
+ if (!android::base::ReadFully(fd_, &header_, sizeof(header_))) {
PLOG(ERROR) << "read header failed";
return false;
}
+
return true;
}
@@ -125,35 +124,52 @@
return false;
}
- std::unique_ptr<CowParserBase> parser;
- switch (header_.prefix.major_version) {
- case 1:
- case 2:
- parser = std::make_unique<CowParserV2>();
- break;
- case 3:
- break;
- default:
- LOG(ERROR) << "Unknown version: " << header_.prefix.major_version;
+ CowParserV2 parser;
+ if (!parser.Parse(fd, header_, label)) {
+ return false;
+ }
+
+ footer_ = parser.footer();
+ fd_size_ = parser.fd_size();
+ last_label_ = parser.last_label();
+ data_loc_ = parser.data_loc();
+ ops_ = std::make_shared<std::vector<CowOperation>>(parser.ops()->size());
+
+ // Translate the operation buffer from on disk to in memory
+ for (size_t i = 0; i < parser.ops()->size(); i++) {
+ const auto& v2_op = parser.ops()->at(i);
+
+ auto& new_op = ops_->at(i);
+ new_op.type = v2_op.type;
+ new_op.data_length = v2_op.data_length;
+
+ if (v2_op.new_block > std::numeric_limits<uint32_t>::max()) {
+ LOG(ERROR) << "Out-of-range new block in COW op: " << v2_op;
return false;
- }
+ }
+ new_op.new_block = v2_op.new_block;
- if (!parser->Parse(fd, header_, label)) {
- return false;
+ uint64_t source_info = v2_op.source;
+ if (new_op.type != kCowLabelOp) {
+ source_info &= kCowOpSourceInfoDataMask;
+ if (source_info != v2_op.source) {
+ LOG(ERROR) << "Out-of-range source value in COW op: " << v2_op;
+ return false;
+ }
+ }
+ if (v2_op.compression != kCowCompressNone) {
+ if (compression_type_ == kCowCompressNone) {
+ compression_type_ = v2_op.compression;
+ } else if (compression_type_ != v2_op.compression) {
+ LOG(ERROR) << "COW has mixed compression types which is not supported;"
+ << " previously saw " << compression_type_ << ", got "
+ << v2_op.compression << ", op: " << v2_op;
+ return false;
+ }
+ }
+ new_op.source_info = source_info;
}
- TranslatedCowOps ops_info;
- if (!parser->Translate(&ops_info)) {
- return false;
- }
-
- header_ = ops_info.header;
- ops_ = std::move(ops_info.ops);
- footer_ = parser->footer();
- fd_size_ = parser->fd_size();
- last_label_ = parser->last_label();
- data_loc_ = parser->data_loc();
-
// If we're resuming a write, we're not ready to merge
if (label.has_value()) return true;
return PrepMergeOps();
@@ -648,7 +664,7 @@
};
uint8_t CowReader::GetCompressionType() {
- return header_.compression_algorithm;
+ return compression_type_;
}
ssize_t CowReader::ReadData(const CowOperation* op, void* buffer, size_t buffer_size,
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/inspect_cow.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/inspect_cow.cpp
index 76509de..a291469 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/inspect_cow.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/inspect_cow.cpp
@@ -74,13 +74,13 @@
}
}
-static bool ShowRawOpStreamV2(borrowed_fd fd, const CowHeaderV3& header) {
+static bool ShowRawOpStreamV2(borrowed_fd fd, const CowHeader& header) {
CowParserV2 parser;
if (!parser.Parse(fd, header)) {
LOG(ERROR) << "v2 parser failed";
return false;
}
- for (const auto& op : *parser.get_v2ops()) {
+ for (const auto& op : *parser.ops()) {
std::cout << op << "\n";
if (auto iter = parser.data_loc()->find(op.new_block); iter != parser.data_loc()->end()) {
std::cout << " data loc: " << iter->second << "\n";
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/parser_base.h b/fs_mgr/libsnapshot/libsnapshot_cow/parser_base.h
deleted file mode 100644
index 2783407..0000000
--- a/fs_mgr/libsnapshot/libsnapshot_cow/parser_base.h
+++ /dev/null
@@ -1,53 +0,0 @@
-//
-// Copyright (C) 2023 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#pragma once
-
-#include <optional>
-#include <unordered_map>
-
-#include <android-base/unique_fd.h>
-#include <libsnapshot/cow_format.h>
-
-namespace android {
-namespace snapshot {
-
-struct TranslatedCowOps {
- CowHeaderV3 header;
- std::shared_ptr<std::vector<CowOperationV3>> ops;
-};
-
-class CowParserBase {
- public:
- virtual ~CowParserBase() = default;
-
- virtual bool Parse(android::base::borrowed_fd fd, const CowHeaderV3& header,
- std::optional<uint64_t> label = {}) = 0;
- virtual bool Translate(TranslatedCowOps* out) = 0;
- virtual std::optional<CowFooter> footer() const { return std::nullopt; }
- virtual std::shared_ptr<std::unordered_map<uint64_t, uint64_t>> data_loc() const = 0;
-
- uint64_t fd_size() const { return fd_size_; }
- const std::optional<uint64_t>& last_label() const { return last_label_; }
-
- protected:
- CowHeaderV3 header_ = {};
- uint64_t fd_size_;
- std::optional<uint64_t> last_label_;
-};
-
-} // namespace snapshot
-} // namespace android
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/parser_v2.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/parser_v2.cpp
index 27d437e..8f20317 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/parser_v2.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/parser_v2.cpp
@@ -17,14 +17,13 @@
#include <android-base/file.h>
#include <android-base/logging.h>
-#include "libsnapshot/cow_format.h"
namespace android {
namespace snapshot {
using android::base::borrowed_fd;
-bool CowParserV2::Parse(borrowed_fd fd, const CowHeaderV3& header, std::optional<uint64_t> label) {
+bool CowParserV2::Parse(borrowed_fd fd, const CowHeader& header, std::optional<uint64_t> label) {
auto pos = lseek(fd.get(), 0, SEEK_END);
if (pos < 0) {
PLOG(ERROR) << "lseek end failed";
@@ -48,7 +47,8 @@
return false;
}
- if (header_.prefix.major_version > 2 || header_.prefix.minor_version != 0) {
+ if ((header_.prefix.major_version > kCowVersionMajor) ||
+ (header_.prefix.minor_version != kCowVersionMinor)) {
LOG(ERROR) << "Header version mismatch, "
<< "major version: " << header_.prefix.major_version
<< ", expected: " << kCowVersionMajor
@@ -190,57 +190,11 @@
}
}
- v2_ops_ = ops_buffer;
- v2_ops_->shrink_to_fit();
+ ops_ = ops_buffer;
+ ops_->shrink_to_fit();
data_loc_ = data_loc;
return true;
}
-bool CowParserV2::Translate(TranslatedCowOps* out) {
- out->ops = std::make_shared<std::vector<CowOperationV3>>(v2_ops_->size());
-
- // Translate the operation buffer from on disk to in memory
- for (size_t i = 0; i < out->ops->size(); i++) {
- const auto& v2_op = v2_ops_->at(i);
-
- auto& new_op = out->ops->at(i);
- new_op.type = v2_op.type;
- new_op.data_length = v2_op.data_length;
-
- if (v2_op.new_block > std::numeric_limits<uint32_t>::max()) {
- LOG(ERROR) << "Out-of-range new block in COW op: " << v2_op;
- return false;
- }
- new_op.new_block = v2_op.new_block;
-
- uint64_t source_info = v2_op.source;
- if (new_op.type != kCowLabelOp) {
- source_info &= kCowOpSourceInfoDataMask;
- if (source_info != v2_op.source) {
- LOG(ERROR) << "Out-of-range source value in COW op: " << v2_op;
- return false;
- }
- }
- if (v2_op.compression != kCowCompressNone) {
- if (header_.compression_algorithm == kCowCompressNone) {
- header_.compression_algorithm = v2_op.compression;
- } else if (header_.compression_algorithm != v2_op.compression) {
- LOG(ERROR) << "COW has mixed compression types which is not supported;"
- << " previously saw " << header_.compression_algorithm << ", got "
- << v2_op.compression << ", op: " << v2_op;
- return false;
- }
- }
- new_op.source_info = source_info;
- }
-
- out->header = header_;
- return true;
-}
-
-std::shared_ptr<std::unordered_map<uint64_t, uint64_t>> CowParserV2::data_loc() const {
- return data_loc_;
-}
-
} // namespace snapshot
} // namespace android
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/parser_v2.h b/fs_mgr/libsnapshot/libsnapshot_cow/parser_v2.h
index a70c780..f51ff88 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/parser_v2.h
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/parser_v2.h
@@ -17,31 +17,36 @@
#include <memory>
#include <optional>
+#include <unordered_map>
#include <vector>
#include <android-base/unique_fd.h>
#include <libsnapshot/cow_format.h>
-#include "parser_base.h"
namespace android {
namespace snapshot {
-class CowParserV2 final : public CowParserBase {
+class CowParserV2 {
public:
- bool Parse(android::base::borrowed_fd fd, const CowHeaderV3& header,
- std::optional<uint64_t> label = {}) override;
- bool Translate(TranslatedCowOps* out) override;
- std::optional<CowFooter> footer() const override { return footer_; }
+ bool Parse(android::base::borrowed_fd fd, const CowHeader& header,
+ std::optional<uint64_t> label = {});
const CowHeader& header() const { return header_; }
- std::shared_ptr<std::vector<CowOperationV2>> get_v2ops() { return v2_ops_; }
- std::shared_ptr<std::unordered_map<uint64_t, uint64_t>> data_loc() const override;
+ const std::optional<CowFooter>& footer() const { return footer_; }
+ std::shared_ptr<std::vector<CowOperationV2>> ops() { return ops_; }
+ std::shared_ptr<std::unordered_map<uint64_t, uint64_t>> data_loc() const { return data_loc_; }
+ uint64_t fd_size() const { return fd_size_; }
+ const std::optional<uint64_t>& last_label() const { return last_label_; }
private:
- std::shared_ptr<std::unordered_map<uint64_t, uint64_t>> data_loc_;
bool ParseOps(android::base::borrowed_fd fd, std::optional<uint64_t> label);
- std::shared_ptr<std::vector<CowOperationV2>> v2_ops_;
+
+ CowHeader header_ = {};
std::optional<CowFooter> footer_;
+ std::shared_ptr<std::vector<CowOperationV2>> ops_;
+ std::shared_ptr<std::unordered_map<uint64_t, uint64_t>> data_loc_;
+ uint64_t fd_size_;
+ std::optional<uint64_t> last_label_;
};
} // namespace snapshot
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/writer_v2.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/writer_v2.cpp
index 37324c7..83a9b1b 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/writer_v2.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/writer_v2.cpp
@@ -273,11 +273,10 @@
if (!ReadCowHeader(fd_, &header_v3)) {
return false;
}
-
header_ = header_v3;
CowParserV2 parser;
- if (!parser.Parse(fd_, header_v3, {label})) {
+ if (!parser.Parse(fd_, header_, {label})) {
return false;
}
if (header_.prefix.major_version > 2) {
@@ -293,7 +292,7 @@
footer_.op.num_ops = 0;
InitPos();
- for (const auto& op : *parser.get_v2ops()) {
+ for (const auto& op : *parser.ops()) {
AddOperation(op);
}
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp
index 950d771..8208d67 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp
@@ -112,7 +112,7 @@
return false;
}
- if (!android::base::WriteFully(cow_fd_, &header, header.prefix.header_size)) {
+ if (!android::base::WriteFully(cow_fd_, &header, sizeof(CowHeader))) {
SNAP_PLOG(ERROR) << "Write to header failed";
return false;
}