| // 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. |
| |
| #ifndef ZIRCON_SYSTEM_ULIB_BLOBFS_FORMAT_ASSERTIONS_ |
| #define ZIRCON_SYSTEM_ULIB_BLOBFS_FORMAT_ASSERTIONS_ |
| |
| #include <cstddef> |
| |
| #include <blobfs/format.h> |
| |
| // This file tests the on-disk structures of Blobfs. |
| |
| namespace blobfs { |
| |
| // clang-format off |
| |
| #define PADDING_LENGTH(type, prev, next) \ |
| (offsetof(type, next) - (offsetof(type, prev) + sizeof(type{}.prev))) |
| |
| // Ensure that the members don't change their offsets within the structure |
| static_assert(offsetof(Superblock, magic0) == 0x0); |
| static_assert(offsetof(Superblock, magic1) == 0x8); |
| static_assert(offsetof(Superblock, version) == 0x10); |
| static_assert(offsetof(Superblock, flags) == 0x14); |
| static_assert(offsetof(Superblock, block_size) == 0x18); |
| static_assert(offsetof(Superblock, data_block_count) == 0x20); |
| static_assert(offsetof(Superblock, journal_block_count) == 0x28); |
| static_assert(offsetof(Superblock, inode_count) == 0x30); |
| static_assert(offsetof(Superblock, alloc_block_count) == 0x38); |
| static_assert(offsetof(Superblock, alloc_inode_count) == 0x40); |
| static_assert(offsetof(Superblock, blob_header_next) == 0x48); |
| static_assert(offsetof(Superblock, slice_size) == 0x50); |
| static_assert(offsetof(Superblock, vslice_count) == 0x58); |
| static_assert(offsetof(Superblock, abm_slices) == 0x60); |
| static_assert(offsetof(Superblock, ino_slices) == 0x64); |
| static_assert(offsetof(Superblock, dat_slices) == 0x68); |
| static_assert(offsetof(Superblock, journal_slices) == 0x6c); |
| |
| // Ensure that the padding between two members doesn't change |
| static_assert(PADDING_LENGTH(Superblock, magic0, magic1) == 0); |
| static_assert(PADDING_LENGTH(Superblock, magic1, version) == 0); |
| static_assert(PADDING_LENGTH(Superblock, version, flags) == 0); |
| static_assert(PADDING_LENGTH(Superblock, flags, block_size) == 0); |
| static_assert(PADDING_LENGTH(Superblock, block_size, data_block_count) == 4); |
| static_assert(PADDING_LENGTH(Superblock, data_block_count, journal_block_count) == 0); |
| static_assert(PADDING_LENGTH(Superblock, journal_block_count, inode_count) == 0); |
| static_assert(PADDING_LENGTH(Superblock, inode_count, alloc_block_count) == 0); |
| static_assert(PADDING_LENGTH(Superblock, alloc_block_count, alloc_inode_count) == 0); |
| static_assert(PADDING_LENGTH(Superblock, alloc_inode_count, blob_header_next) == 0); |
| static_assert(PADDING_LENGTH(Superblock, blob_header_next, slice_size) == 0); |
| static_assert(PADDING_LENGTH(Superblock, slice_size, vslice_count) == 0); |
| static_assert(PADDING_LENGTH(Superblock, vslice_count, abm_slices) == 0); |
| static_assert(PADDING_LENGTH(Superblock, abm_slices, ino_slices) == 0); |
| static_assert(PADDING_LENGTH(Superblock, ino_slices, dat_slices) == 0); |
| static_assert(PADDING_LENGTH(Superblock, dat_slices, journal_slices) == 0); |
| static_assert(PADDING_LENGTH(Superblock, journal_slices, reserved) == 0); |
| |
| // Ensure that the padding at the end of structure doesn't change |
| static_assert(sizeof(Superblock) == |
| offsetof(Superblock, reserved) + sizeof(Superblock{}.reserved)); |
| |
| // Ensure that the members don't change their offsets within the structure |
| static_assert(offsetof(fs::JournalInfo, magic) == 0x0); |
| static_assert(offsetof(fs::JournalInfo, start_block) == 0x08); |
| static_assert(offsetof(fs::JournalInfo, reserved) == 0x10); |
| static_assert(offsetof(fs::JournalInfo, timestamp) == 0x18); |
| static_assert(offsetof(fs::JournalInfo, checksum) == 0x20); |
| |
| // Ensure that the padding between two members doesn't change |
| static_assert(PADDING_LENGTH(fs::JournalInfo, magic, start_block) == 0); |
| static_assert(PADDING_LENGTH(fs::JournalInfo, start_block, reserved) == 0); |
| static_assert(PADDING_LENGTH(fs::JournalInfo, reserved, timestamp) == 0); |
| static_assert(PADDING_LENGTH(fs::JournalInfo, timestamp, checksum) == 0); |
| |
| // Ensure that the padding at the end of structure doesn't change |
| static_assert(sizeof(fs::JournalInfo) == |
| offsetof(fs::JournalInfo, checksum) + |
| sizeof(fs::JournalInfo{}.checksum) + 4); |
| |
| // Ensure that the members don't change their offsets within the structure. |
| static_assert(offsetof(fs::JournalPrefix, magic) == 0x0); |
| static_assert(offsetof(fs::JournalPrefix, sequence_number) == 0x8); |
| static_assert(offsetof(fs::JournalPrefix, flags) == 0x10); |
| |
| // Ensure that the padding between members doesn't change. |
| static_assert(PADDING_LENGTH(fs::JournalPrefix, magic, sequence_number) == 0); |
| static_assert(PADDING_LENGTH(fs::JournalPrefix, sequence_number, flags) == 0); |
| |
| // Ensure that the members don't change their offsets within the structure. |
| static_assert(offsetof(fs::JournalHeaderBlock, prefix) == 0x0); |
| static_assert(offsetof(fs::JournalHeaderBlock, payload_blocks) == 0x20); |
| static_assert(offsetof(fs::JournalHeaderBlock, target_blocks) == 0x28); |
| static_assert(offsetof(fs::JournalHeaderBlock, target_flags) == 0x1560); |
| |
| // Ensure that the padding between members doesn't change. |
| static_assert(PADDING_LENGTH(fs::JournalHeaderBlock, prefix, payload_blocks) == 0); |
| static_assert(PADDING_LENGTH(fs::JournalHeaderBlock, payload_blocks, target_blocks) == 0); |
| static_assert(PADDING_LENGTH(fs::JournalHeaderBlock, target_blocks, target_flags) == 0); |
| |
| // Ensure that the members don't change their offsets within the structure. |
| static_assert(offsetof(fs::JournalCommitBlock, prefix) == 0x0); |
| static_assert(offsetof(fs::JournalCommitBlock, checksum) == 0x20); |
| |
| // Ensure that the padding between members doesn't change. |
| static_assert(PADDING_LENGTH(fs::JournalCommitBlock, prefix, checksum) == 0); |
| |
| // Ensure that the members don't change their offsets within the structure |
| static_assert(offsetof(NodePrelude, flags) == 0x0); |
| static_assert(offsetof(NodePrelude, version) == 0x02); |
| static_assert(offsetof(NodePrelude, next_node) == 0x4); |
| |
| // Ensure that the padding between two members doesn't change |
| static_assert(PADDING_LENGTH(NodePrelude, flags, version) == 0); |
| static_assert(PADDING_LENGTH(NodePrelude, version, next_node) == 0); |
| |
| // Ensure that the padding at the end of structure doesn't change |
| static_assert(sizeof(NodePrelude) == |
| offsetof(NodePrelude, next_node) + sizeof(NodePrelude{}.next_node)); |
| |
| // Ensure that the members don't change their offsets within the structure |
| static_assert(offsetof(Inode, header) == 0x00); |
| static_assert(offsetof(Inode, merkle_root_hash) == 0x08); |
| static_assert(offsetof(Inode, blob_size) == 0x28); |
| static_assert(offsetof(Inode, block_count) == 0x30); |
| static_assert(offsetof(Inode, extent_count) == 0x34); |
| static_assert(offsetof(Inode, reserved) == 0x36); |
| static_assert(offsetof(Inode, extents) == 0x38); |
| |
| // Ensure that the padding between two members doesn't change |
| static_assert(PADDING_LENGTH(Inode, header, merkle_root_hash) == 0); |
| static_assert(PADDING_LENGTH(Inode, merkle_root_hash, blob_size) == 0); |
| static_assert(PADDING_LENGTH(Inode, blob_size, block_count) == 0); |
| static_assert(PADDING_LENGTH(Inode, block_count, extent_count) == 0); |
| static_assert(PADDING_LENGTH(Inode, extent_count, reserved) == 0); |
| static_assert(PADDING_LENGTH(Inode, reserved, extents) == 0); |
| |
| // Ensure that the padding at the end of structure doesn't change |
| static_assert(sizeof(Inode) == offsetof(Inode, extents) + sizeof(Inode{}.extents)); |
| |
| // Ensure that the members don't change their offsets within the structure |
| static_assert(offsetof(ExtentContainer, header) == 0x00); |
| static_assert(offsetof(ExtentContainer, previous_node) == 0x08); |
| static_assert(offsetof(ExtentContainer, extent_count) == 0x0c); |
| static_assert(offsetof(ExtentContainer, reserved) == 0x0e); |
| static_assert(offsetof(ExtentContainer, extents) == 0x10); |
| |
| // Ensure that the padding between two members doesn't change |
| static_assert(PADDING_LENGTH(ExtentContainer, header, previous_node) == 0); |
| static_assert(PADDING_LENGTH(ExtentContainer, previous_node, extent_count) == 0); |
| static_assert(PADDING_LENGTH(ExtentContainer, extent_count, reserved) == 0); |
| static_assert(PADDING_LENGTH(ExtentContainer, reserved, extents) == 0); |
| |
| // Ensure that the padding at the end of structure doesn't change |
| static_assert(sizeof(ExtentContainer) == |
| offsetof(ExtentContainer, extents) + sizeof(ExtentContainer{}.extents)); |
| |
| // clang-format on |
| |
| } // namespace blobfs |
| |
| #endif // ZIRCON_SYSTEM_ULIB_BLOBFS_FORMAT_ASSERTIONS_ |