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

Commit ad5cc05c authored by Akilesh Kailash's avatar Akilesh Kailash Committed by Gerrit Code Review
Browse files

Merge "libsnapshot: Changes to AddCopy() API"

parents 9457a9ab b23bf16e
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -52,8 +52,9 @@ class ICowWriter {
    virtual ~ICowWriter() {}

    // Encode an operation that copies the contents of |old_block| to the
    // location of |new_block|.
    bool AddCopy(uint64_t new_block, uint64_t old_block);
    // location of |new_block|. 'num_blocks' is the number of contiguous
    // COPY operations from |old_block| to |new_block|.
    bool AddCopy(uint64_t new_block, uint64_t old_block, uint64_t num_blocks = 1);

    // Encode a sequence of raw blocks. |size| must be a multiple of the block size.
    bool AddRawBlocks(uint64_t new_block_start, const void* data, size_t size);
@@ -84,7 +85,7 @@ class ICowWriter {
    const CowOptions& options() { return options_; }

  protected:
    virtual bool EmitCopy(uint64_t new_block, uint64_t old_block) = 0;
    virtual bool EmitCopy(uint64_t new_block, uint64_t old_block, uint64_t num_blocks = 1) = 0;
    virtual bool EmitRawBlocks(uint64_t new_block_start, const void* data, size_t size) = 0;
    virtual bool EmitXorBlocks(uint32_t new_block_start, const void* data, size_t size,
                               uint32_t old_block, uint16_t offset) = 0;
@@ -122,7 +123,7 @@ class CowWriter : public ICowWriter {
    uint32_t GetCowVersion() { return header_.major_version; }

  protected:
    virtual bool EmitCopy(uint64_t new_block, uint64_t old_block) override;
    virtual bool EmitCopy(uint64_t new_block, uint64_t old_block, uint64_t num_blocks = 1) override;
    virtual bool EmitRawBlocks(uint64_t new_block_start, const void* data, size_t size) override;
    virtual bool EmitXorBlocks(uint32_t new_block_start, const void* data, size_t size,
                               uint32_t old_block, uint16_t offset) override;
+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ class MockSnapshotWriter : public ISnapshotWriter {
    // Returns true if AddCopy() operations are supported.
    MOCK_METHOD(bool, SupportsCopyOperation, (), (const override));

    MOCK_METHOD(bool, EmitCopy, (uint64_t, uint64_t), (override));
    MOCK_METHOD(bool, EmitCopy, (uint64_t, uint64_t, uint64_t), (override));
    MOCK_METHOD(bool, EmitRawBlocks, (uint64_t, const void*, size_t), (override));
    MOCK_METHOD(bool, EmitXorBlocks, (uint32_t, const void*, size_t, uint32_t, uint16_t),
                (override));
+2 −2
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ class CompressedSnapshotWriter final : public ISnapshotWriter {
    bool VerifyMergeOps() const noexcept;

  protected:
    bool EmitCopy(uint64_t new_block, uint64_t old_block) override;
    bool EmitCopy(uint64_t new_block, uint64_t old_block, uint64_t num_blocks = 1) override;
    bool EmitRawBlocks(uint64_t new_block_start, const void* data, size_t size) override;
    bool EmitXorBlocks(uint32_t new_block_start, const void* data, size_t size, uint32_t old_block,
                       uint16_t offset) override;
@@ -113,7 +113,7 @@ class OnlineKernelSnapshotWriter final : public ISnapshotWriter {
    bool EmitZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) override;
    bool EmitXorBlocks(uint32_t new_block_start, const void* data, size_t size, uint32_t old_block,
                       uint16_t offset) override;
    bool EmitCopy(uint64_t new_block, uint64_t old_block) override;
    bool EmitCopy(uint64_t new_block, uint64_t old_block, uint64_t num_blocks = 1) override;
    bool EmitLabel(uint64_t label) override;
    bool EmitSequenceData(size_t num_ops, const uint32_t* data) override;

+42 −0
Original line number Diff line number Diff line
@@ -62,6 +62,48 @@ class StringSink : public IByteSink {
    std::string stream_;
};

TEST_F(CowTest, CopyContiguous) {
    CowOptions options;
    options.cluster_ops = 0;
    CowWriter writer(options);

    ASSERT_TRUE(writer.Initialize(cow_->fd));

    ASSERT_TRUE(writer.AddCopy(10, 1000, 100));
    ASSERT_TRUE(writer.Finalize());
    ASSERT_EQ(lseek(cow_->fd, 0, SEEK_SET), 0);

    CowReader reader;
    CowHeader header;
    CowFooter footer;
    ASSERT_TRUE(reader.Parse(cow_->fd));
    ASSERT_TRUE(reader.GetHeader(&header));
    ASSERT_TRUE(reader.GetFooter(&footer));
    ASSERT_EQ(header.magic, kCowMagicNumber);
    ASSERT_EQ(header.major_version, kCowVersionMajor);
    ASSERT_EQ(header.minor_version, kCowVersionMinor);
    ASSERT_EQ(header.block_size, options.block_size);
    ASSERT_EQ(footer.op.num_ops, 100);

    auto iter = reader.GetOpIter();
    ASSERT_NE(iter, nullptr);
    ASSERT_FALSE(iter->Done());

    size_t i = 0;
    while (!iter->Done()) {
        auto op = &iter->Get();
        ASSERT_EQ(op->type, kCowCopyOp);
        ASSERT_EQ(op->compression, kCowCompressNone);
        ASSERT_EQ(op->data_length, 0);
        ASSERT_EQ(op->new_block, 10 + i);
        ASSERT_EQ(op->source, 1000 + i);
        iter->Next();
        i += 1;
    }

    ASSERT_EQ(i, 100);
}

TEST_F(CowTest, ReadWrite) {
    CowOptions options;
    options.cluster_ops = 0;
+22 −10
Original line number Diff line number Diff line
@@ -38,11 +38,16 @@ static_assert(sizeof(off_t) == sizeof(uint64_t));
using android::base::borrowed_fd;
using android::base::unique_fd;

bool ICowWriter::AddCopy(uint64_t new_block, uint64_t old_block) {
    if (!ValidateNewBlock(new_block)) {
bool ICowWriter::AddCopy(uint64_t new_block, uint64_t old_block, uint64_t num_blocks) {
    CHECK(num_blocks != 0);

    for (size_t i = 0; i < num_blocks; i++) {
        if (!ValidateNewBlock(new_block + i)) {
            return false;
        }
    return EmitCopy(new_block, old_block);
    }

    return EmitCopy(new_block, old_block, num_blocks);
}

bool ICowWriter::AddRawBlocks(uint64_t new_block_start, const void* data, size_t size) {
@@ -286,13 +291,20 @@ bool CowWriter::OpenForAppend(uint64_t label) {
    return EmitClusterIfNeeded();
}

bool CowWriter::EmitCopy(uint64_t new_block, uint64_t old_block) {
bool CowWriter::EmitCopy(uint64_t new_block, uint64_t old_block, uint64_t num_blocks) {
    CHECK(!merge_in_progress_);

    for (size_t i = 0; i < num_blocks; i++) {
        CowOperation op = {};
        op.type = kCowCopyOp;
    op.new_block = new_block;
    op.source = old_block;
    return WriteOperation(op);
        op.new_block = new_block + i;
        op.source = old_block + i;
        if (!WriteOperation(op)) {
            return false;
        }
    }

    return true;
}

bool CowWriter::EmitRawBlocks(uint64_t new_block_start, const void* data, size_t size) {
Loading