Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ccb347e authored by Kelvin Zhang's avatar Kelvin Zhang
Browse files

Turn CowOperationType into an enum

There's a bug previsouly where we compare return value of
GetCowOpSourceInfoData() with CowOperationType. Such bugs are possible
because cow operation enums are weakly typed integers. Turn
CowOperationType into strongly typed enum to prevent such bugs.

Test: th
Bug: 304602386
Change-Id: If6941a4740c374ed066cf0aee9e52f4df05a9b38
parent 0ca4e8f4
Loading
Loading
Loading
Loading
+24 −12
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#include <stdint.h>

#include <limits>
#include <optional>
#include <string_view>

@@ -119,10 +120,30 @@ struct CowHeaderV3 : public CowHeader {
    uint32_t compression_algorithm;
} __attribute__((packed));

enum class CowOperationType : uint8_t {
    kCowCopyOp = 1,
    kCowReplaceOp = 2,
    kCowZeroOp = 3,
    kCowLabelOp = 4,
    kCowClusterOp = 5,
    kCowXorOp = 6,
    kCowSequenceOp = 7,
    kCowFooterOp = std::numeric_limits<uint8_t>::max(),
};

static constexpr CowOperationType kCowCopyOp = CowOperationType::kCowCopyOp;
static constexpr CowOperationType kCowReplaceOp = CowOperationType::kCowReplaceOp;
static constexpr CowOperationType kCowZeroOp = CowOperationType::kCowZeroOp;
static constexpr CowOperationType kCowLabelOp = CowOperationType::kCowLabelOp;
static constexpr CowOperationType kCowClusterOp = CowOperationType::kCowClusterOp;
static constexpr CowOperationType kCowXorOp = CowOperationType::kCowXorOp;
static constexpr CowOperationType kCowSequenceOp = CowOperationType::kCowSequenceOp;
static constexpr CowOperationType kCowFooterOp = CowOperationType::kCowFooterOp;

// This structure is the same size of a normal Operation, but is repurposed for the footer.
struct CowFooterOperation {
    // The operation code (always kCowFooterOp).
    uint8_t type;
    CowOperationType type;

    // If this operation reads from the data section of the COW, this contains
    // the compression type of that data (see constants below).
@@ -141,7 +162,7 @@ struct CowFooterOperation {
// V2 version of COW. On disk format for older devices
struct CowOperationV2 {
    // The operation code (see the constants and structures below).
    uint8_t type;
    CowOperationType type;

    // If this operation reads from the data section of the COW, this contains
    // the compression type of that data (see constants below).
@@ -176,7 +197,7 @@ struct CowOperationV2 {
// The on disk format of cow (currently ==  CowOperation)
struct CowOperationV3 {
    // The operation code (see the constants and structures below).
    uint8_t type;
    CowOperationType type;

    // If this operation reads from the data section of the COW, this contains
    // the length.
@@ -201,15 +222,6 @@ struct CowOperationV3 {

static_assert(sizeof(CowOperationV2) == sizeof(CowFooterOperation));

static constexpr uint8_t kCowCopyOp = 1;
static constexpr uint8_t kCowReplaceOp = 2;
static constexpr uint8_t kCowZeroOp = 3;
static constexpr uint8_t kCowLabelOp = 4;
static constexpr uint8_t kCowClusterOp = 5;
static constexpr uint8_t kCowXorOp = 6;
static constexpr uint8_t kCowSequenceOp = 7;
static constexpr uint8_t kCowFooterOp = -1;

enum CowCompressionAlgorithm : uint8_t {
    kCowCompressNone = 0,
    kCowCompressGz = 1,
+1 −1
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ namespace snapshot {

using android::base::unique_fd;

std::ostream& EmitCowTypeString(std::ostream& os, uint8_t cow_type) {
std::ostream& EmitCowTypeString(std::ostream& os, CowOperationType cow_type) {
    switch (cow_type) {
        case kCowCopyOp:
            return os << "kCowCopyOp";
+1 −1
Original line number Diff line number Diff line
@@ -369,7 +369,7 @@ bool CowWriterV2::CompressBlocks(size_t num_blocks, const void* data) {
}

bool CowWriterV2::EmitBlocks(uint64_t new_block_start, const void* data, size_t size,
                             uint64_t old_block, uint16_t offset, uint8_t type) {
                             uint64_t old_block, uint16_t offset, CowOperationType type) {
    CHECK(!merge_in_progress_);
    const uint8_t* iter = reinterpret_cast<const uint8_t*>(data);

+1 −1
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ class CowWriterV2 : public CowWriterBase {
    bool EmitCluster();
    bool EmitClusterIfNeeded();
    bool EmitBlocks(uint64_t new_block_start, const void* data, size_t size, uint64_t old_block,
                    uint16_t offset, uint8_t type);
                    uint16_t offset, CowOperationType type);
    void SetupHeaders();
    void SetupWriteOptions();
    bool ParseOptions();
+1 −1
Original line number Diff line number Diff line
@@ -230,7 +230,7 @@ bool CowWriterV3::EmitXorBlocks(uint32_t new_block_start, const void* data, size
}

bool CowWriterV3::EmitBlocks(uint64_t new_block_start, const void* data, size_t size,
                             uint64_t old_block, uint16_t offset, uint8_t type) {
                             uint64_t old_block, uint16_t offset, CowOperationType type) {
    const size_t num_blocks = (size / header_.block_size);
    for (size_t i = 0; i < num_blocks; i++) {
        const uint8_t* const iter =
Loading