fxfs/serialized_types.rs
1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! # On-disk versioning
6//!
7//! This module manages serialization and deserialization of FxFS structures to disk.
8//!
9//! In FxFS, on-disk layout is deferred to serialization libraries (i.e.
10//! [bincode](https://github.com/bincode-org/bincode#is-bincode-suitable-for-storage), serde).
11//! Stability of these layouts depends on both struct/enum stability and serialization libraries.
12//!
13//! This module provides struct/enum stability by maintaining a generation of types and a
14//! means to upgrade from older versions to newer ones.
15//!
16//! The trait mechanism used is flexible enough to allow specific versions to use differing
17//! serialization code if we ever require it.
18//!
19//! ## Traits
20//!
21//! All serialization is done with serde so [Serialize] and [Deserialize] traits must be derived
22//! for all types and sub-types.
23//!
24//! All versioned, serializable struct/enum type should have the [Versioned] trait.
25//! The most recent version of a type should also have the [VersionedLatest] trait.
26//! These traits are largely implemented for you via the `versioned_type!` macro as follows:
27//!
28//! ```ignore
29//! versioned_type! {
30//! 3.. => SuperBlockHeaderV3,
31//! 2.. => SuperBlockHeaderV2,
32//! 1.. => SuperBlockHeaderV1,
33//! }
34//!
35//! // Note the reuse of SuperBlockRecordV1 for two versions.
36//! versioned_type! {
37//! 3.. => SuperBlockRecordV2,
38//! 1.. => SuperBlockRecordV1,
39//! }
40//! ```
41//!
42//! The user is required to implement [From] to migrate from one version to the next.
43//! The above macros will implement further [From] traits allowing direct upgrade from any version
44//! to the latest. [VersionedLatest] provides a `deserialize_from_version` method that can be
45//! used to deserialize any supported version and then upgrade it to the latest format.
46//!
47//! ## Conventions
48//!
49//! There are limits to how automated this process can be, so we rely heavily on conventions.
50//!
51//! * Every versioned type should have a monotonically increasing `Vn` suffix for each generation.
52//! * Every versioned sub-type (e.g. child of a struct) should also have `Vn` suffix.
53//! * In type definitions, all versioned child types should be referred to explicitly with their
54//! `Vn` suffix. This prevents us from accidentally changing a version by changing a sub-type.
55
56mod traits;
57
58pub const DEFAULT_MAX_SERIALIZED_RECORD_SIZE: u64 = 4096;
59
60// Re-export the traits we need.
61pub use fxfs_macros::{Migrate, Versioned, migrate_nodefault, migrate_to_version, versioned_type};
62pub use traits::{Version, Versioned, VersionedLatest};
63
64// For test use, we add [Versioned] and [VersionedLatest] to primitive integer types (i32, ...).
65#[cfg(test)]
66pub mod test_traits;
67
68#[cfg(test)]
69mod tests;
70
71// Re-export all Fxfs types.
72mod types;
73pub use types::{
74 EARLIEST_SUPPORTED_VERSION, FIRST_EXTENT_IN_SUPERBLOCK_VERSION, LATEST_VERSION,
75 SMALL_SUPERBLOCK_VERSION, get_type_fingerprints,
76};