blob: e472320eab59df29b40385eadb8579cf379c8e9d [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 <lib/syslog/cpp/macros.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <limits>
#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) {
FX_LOGS(DEBUG) << "magic: " << std::setw(10) << info.magic;
FX_LOGS(DEBUG) << "major version: " << std::setw(10) << info.major_version;
FX_LOGS(DEBUG) << "minor version: " << std::setw(10) << info.minor_version;
FX_LOGS(DEBUG) << "flags: " << std::setw(10) << info.flags;
FX_LOGS(DEBUG) << "data blocks: " << std::setw(10) << info.data_blocks;
FX_LOGS(DEBUG) << "directory size: " << std::setw(10) << info.directory_size;
FX_LOGS(DEBUG) << "directory entries: " << std::setw(10) << info.directory_entries;
FX_LOGS(DEBUG) << "block size @ " << std::setw(10) << info.block_size;
FX_LOGS(DEBUG) << "num directory entry blocks " << std::setw(10) << info.directory_ent_blocks;
FX_LOGS(DEBUG) << "directory entry start block @ " << std::setw(10)
<< info.directory_ent_start_block;
}
} // namespace
// Validate the metadata for the superblock
zx_status_t CheckSuperblock(const Superblock* info) {
if (info->magic != kFactoryfsMagic) {
FX_LOGS(ERROR) << "bad magic";
return ZX_ERR_IO_DATA_INTEGRITY;
}
if (info->major_version != kFactoryfsMajorVersion) {
FX_LOGS(ERROR) << "FS Version: " << std::setfill('0') << std::setw(8) << std::hex
<< info->major_version << ". Driver version: " << std::setw(8)
<< kFactoryfsMajorVersion;
DumpSuperblock(*info);
return ZX_ERR_IO_DATA_INTEGRITY;
}
if (info->major_version != kFactoryfsMajorVersion) {
FX_LOGS(ERROR) << "FS Major Version: " << std::setfill('0') << std::setw(8) << std::hex
<< info->major_version << ". Driver version: " << std::setw(8)
<< kFactoryfsMajorVersion;
DumpSuperblock(*info);
return ZX_ERR_IO_DATA_INTEGRITY;
}
if (info->minor_version != kFactoryfsMinorVersion) {
FX_LOGS(ERROR) << "FS Minor Version: " << std::setfill('0') << std::setw(8) << std::hex
<< info->major_version << ". Driver version: " << std::setw(8)
<< kFactoryfsMinorVersion;
DumpSuperblock(*info);
return ZX_ERR_IO_DATA_INTEGRITY;
}
if (info->block_size != kFactoryfsBlockSize) {
FX_LOGS(ERROR) << "bsz " << info->block_size << " unsupported";
DumpSuperblock(*info);
return ZX_ERR_IO_DATA_INTEGRITY;
}
// Check if flags (currently unused) are zeroed out correctly.
if (info->flags != 0) {
FX_LOGS(ERROR) << "flags set to incorrect value: " << std::setfill('0') << std::setw(8)
<< std::hex << info->flags;
DumpSuperblock(*info);
return ZX_ERR_IO_DATA_INTEGRITY;
}
for (uint32_t i = 0; i < kFactoryfsReserved; i++) {
if (info->reserved[i]) {
FX_LOGS(ERROR) << "reserved bits are not zeroed out correctly";
DumpSuperblock(*info);
return ZX_ERR_IO_DATA_INTEGRITY;
}
}
DumpSuperblock(*info);
FX_LOGS(DEBUG) << "Checksuperblock success";
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