blob: 5c246cbca4529a2f28f4dc1a5aed7120843a6d25 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/storage/lib/vfs/cpp/journal/header_view.h"
#include <lib/cksum.h>
#include <string.h>
namespace fs {
namespace {
// Returns true if the |header| has kJournalEntryMagic as magic number and matches the
// |sequence_number|
bool IsJournalMetadata(const JournalHeaderBlock* header, uint64_t sequence_number) {
if (header->prefix.magic != kJournalEntryMagic) {
return false;
}
if (header->prefix.sequence_number != sequence_number) {
return false;
}
return true;
}
// Returns true if the |header| IsJournalMetadata and is of type JournalObjectType::kHeader or
// JournalObjectType::kRevocation.
bool IsHeader(const JournalHeaderBlock* header, uint64_t sequence_number) {
if (!IsJournalMetadata(header, sequence_number)) {
return false;
}
if (header->prefix.ObjectType() != JournalObjectType::kHeader &&
header->prefix.ObjectType() != JournalObjectType::kRevocation) {
return false;
}
return true;
}
} // namespace
JournalHeaderView::JournalHeaderView(cpp20::span<uint8_t> block)
: header_(reinterpret_cast<JournalHeaderBlock*>(block.data())) {
ZX_ASSERT(block.size_bytes() >= kJournalBlockSize);
}
JournalHeaderView::JournalHeaderView(cpp20::span<uint8_t> block, uint64_t payload_blocks,
uint64_t sequence_number)
: header_(reinterpret_cast<JournalHeaderBlock*>(block.data())) {
ZX_ASSERT(block.size_bytes() >= kJournalBlockSize);
Encode(payload_blocks, sequence_number);
}
void JournalHeaderView::Encode(uint64_t payload_blocks, uint64_t sequence_number) {
memset(header_, 0, kJournalBlockSize);
header_->prefix.magic = kJournalEntryMagic;
header_->prefix.sequence_number = sequence_number;
header_->prefix.flags = kJournalPrefixFlagHeader;
header_->payload_blocks = payload_blocks;
}
fpromise::result<JournalHeaderView, zx_status_t> JournalHeaderView::Create(
cpp20::span<uint8_t> block, uint64_t sequence_number) {
if (block.size_bytes() < kJournalBlockSize) {
return fpromise::error(ZX_ERR_BUFFER_TOO_SMALL);
}
if (!IsHeader(reinterpret_cast<const JournalHeaderBlock*>(block.data()), sequence_number)) {
return fpromise::error(ZX_ERR_BAD_STATE);
}
return fpromise::ok(JournalHeaderView(block));
}
} // namespace fs