blob: a1efcb4466910ccc06bcba6e0da6e0c2f1de9617 [file] [log] [blame]
// Copyright 2020 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/factory/factoryfs/superblock.h"
#include <inttypes.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <limits>
#include <fs/trace.h>
#ifdef __Fuchsia__
#include <fuchsia/hardware/block/c/fidl.h>
#include <fuchsia/hardware/block/volume/c/fidl.h>
#endif
namespace factoryfs {
namespace {
// Dumps the content of superblock.
void DumpSuperblock(const Superblock& info) {
FS_TRACE_DEBUG("factoryfs: magic: %10lu\n", info.magic);
FS_TRACE_DEBUG("factoryfs: major version: %10u\n", info.major_version);
FS_TRACE_DEBUG("factoryfs: minor version: %10u\n", info.minor_version);
FS_TRACE_DEBUG("factoryfs: flags: %10u\n", info.flags);
FS_TRACE_DEBUG("factoryfs: data blocks: %10u\n", info.data_blocks);
FS_TRACE_DEBUG("factoryfs: directory size: %10u\n", info.directory_size);
FS_TRACE_DEBUG("factoryfs: directory entries: %10u\n", info.directory_entries);
FS_TRACE_DEBUG("factoryfs: block size @ %10u\n", info.info.block_size);
FS_TRACE_DEBUG("factoryfs: num directory entry blocks %10u\n", info.directory_ent_blocks);
FS_TRACE_DEBUG("factoryfs: directory entry start block @ %10u\n", info.directory_ent_start_block);
}
} // namespace
// Validate the metadata for the superblock
zx_status_t CheckSuperblock(const Superblock* info) {
if (info->magic != kFactoryfsMagic) {
FS_TRACE_ERROR("factoryfs: bad magic\n");
return ZX_ERR_IO_DATA_INTEGRITY;
}
if (info->major_version != kFactoryfsMajorVersion) {
FS_TRACE_ERROR("factoryfs: FS Version: %08x. Driver version: %08x\n", info->major_version,
kFactoryfsMajorVersion);
DumpSuperblock(*info);
return ZX_ERR_IO_DATA_INTEGRITY;
}
if (info->major_version != kFactoryfsMajorVersion) {
FS_TRACE_ERROR("factoryfs: FS Major Version: %08x. Driver version: %08x\n", info->major_version,
kFactoryfsMajorVersion);
DumpSuperblock(*info);
return ZX_ERR_IO_DATA_INTEGRITY;
}
if (info->minor_version != kFactoryfsMinorVersion) {
FS_TRACE_ERROR("factoryfs: FS Minor Version: %08x. Driver version: %08x\n", info->major_version,
kFactoryfsMinorVersion);
DumpSuperblock(*info);
return ZX_ERR_IO_DATA_INTEGRITY;
}
if (info->block_size != kFactoryfsBlockSize) {
FS_TRACE_ERROR("factoryfs: bsz %u unsupported\n", info->block_size);
DumpSuperblock(*info);
return ZX_ERR_IO_DATA_INTEGRITY;
}
// Check if flags (currently unused) are zeroed out correctly.
if (info->flags != 0) {
FS_TRACE_ERROR("factoryfs: flags set to incorrect value: %08x\n", info->flags);
DumpSuperblock(*info);
return ZX_ERR_IO_DATA_INTEGRITY;
}
for (uint32_t i = 0; i < kFactoryfsReserved; i++) {
if (info->reserved[i]) {
FS_TRACE_ERROR("factoryfs: reserved bits are not zeroed out correctly\n");
DumpSuperblock(*info);
return ZX_ERR_IO_DATA_INTEGRITY;
}
}
DumpSuperblock(*info);
FS_TRACE_DEBUG("Checksuperblock success\n");
return ZX_OK;
}
void InitializeSuperblock(uint64_t block_count, Superblock* info) {
memset(info, 0x00, sizeof(*info));
info->magic = kFactoryfsMagic;
info->major_version = kFactoryfsMajorVersion;
info->minor_version = kFactoryfsMinorVersion;
info->flags = 0;
info->block_size = kFactoryfsBlockSize;
info->data_blocks = 1;
info->directory_ent_blocks = 1;
info->directory_ent_start_block = kDirenStartBlock;
info->directory_entries = 1;
info->directory_size = info->directory_ent_blocks * info->directory_entries * kFactoryfsBlockSize;
}
} // namespace factoryfs