fxfs/serialized_types/
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
5use crate::lsm_tree::{
6    PersistentLayerHeader, PersistentLayerHeaderV39, PersistentLayerInfo, PersistentLayerInfoV39,
7};
8use crate::object_store::allocator::{
9    AllocatorInfo, AllocatorInfoV32, AllocatorKey, AllocatorKeyV32, AllocatorValue,
10    AllocatorValueV32,
11};
12use crate::object_store::journal::super_block::{
13    SuperBlockHeader, SuperBlockHeaderV32, SuperBlockRecord, SuperBlockRecordV40,
14    SuperBlockRecordV41, SuperBlockRecordV43, SuperBlockRecordV46, SuperBlockRecordV47,
15    SuperBlockRecordV49, SuperBlockRecordV50,
16};
17use crate::object_store::journal::{
18    JournalRecord, JournalRecordV40, JournalRecordV41, JournalRecordV42, JournalRecordV43,
19    JournalRecordV46, JournalRecordV47, JournalRecordV49, JournalRecordV50,
20};
21use crate::object_store::object_record::{
22    FsverityMetadata, FsverityMetadataV33, FsverityMetadataV50, ObjectKey, ObjectKeyV40,
23    ObjectKeyV43, ObjectValue, ObjectValueV40, ObjectValueV41, ObjectValueV46, ObjectValueV47,
24    ObjectValueV49, ObjectValueV50,
25};
26use crate::object_store::transaction::{
27    Mutation, MutationV40, MutationV41, MutationV43, MutationV46, MutationV47, MutationV49,
28    MutationV50,
29};
30use crate::object_store::{
31    EncryptedMutations, EncryptedMutationsV40, EncryptedMutationsV49, StoreInfo, StoreInfoV40,
32    StoreInfoV49, StoreInfoV52,
33};
34use crate::serialized_types::{Version, Versioned, VersionedLatest, versioned_type};
35use std::collections::BTreeMap;
36
37/// The latest version of on-disk filesystem format.
38///
39/// If all layer files are compacted the the journal flushed, and super-block
40/// both rewritten, all versions should match this value.
41///
42/// If making a breaking change, please see EARLIEST_SUPPORTED_VERSION (below).
43///
44/// IMPORTANT: When changing this (major or minor), update the list of possible versions at
45/// https://cs.opensource.google/fuchsia/fuchsia/+/main:third_party/cobalt_config/fuchsia/local_storage/versions.txt.
46pub const LATEST_VERSION: Version = Version { major: 52, minor: 0 };
47
48/// The earliest supported version of the on-disk filesystem format.
49///
50/// When a breaking change is made:
51/// 1) LATEST_VERSION should have it's major component increased (see above).
52/// 2) EARLIEST_SUPPORTED_VERSION should be set to the new LATEST_VERSION.
53/// 3) The SuperBlockHeader version (below) should also be set to the new LATEST_VERSION.
54///
55/// Also check the constant version numbers above for any code cleanup that can happen.
56pub const EARLIEST_SUPPORTED_VERSION: Version = Version { major: 40, minor: 0 };
57
58/// From this version of the filesystem, we shrink the size of the extents that are reserved for
59/// the superblock and root-parent store to a single block.
60pub const SMALL_SUPERBLOCK_VERSION: Version = Version { major: 44, minor: 0 };
61
62/// From this version of the filesystem, the superblock explicitly includes a record for it's
63/// first extent. Prior to this, the first extent was assumed based on hard-coded location.
64pub const FIRST_EXTENT_IN_SUPERBLOCK_VERSION: Version = Version { major: 45, minor: 0 };
65
66/// This trait prevents types from showing up in `versioned_types` multiple times. `versioned_types`
67/// implements this trait for every type passed to it. If a type is listed multiple times then this
68/// trait will be implemented for the type multiple times which will fail to compile.
69#[allow(dead_code)]
70trait UniqueVersionForType {}
71
72macro_rules! versioned_types {
73    ( $( $name:ident { $latest:literal.. => $latest_type:ty $(, $major:literal.. => $type:ty )* $(,)? } )+ ) => {
74        $(
75            static_assertions::assert_type_eq_all!($name, $latest_type);
76
77            versioned_type! {
78                $latest.. => $latest_type,
79                $( $major.. => $type ),*
80            }
81
82            impl UniqueVersionForType for $latest_type {}
83            $( impl UniqueVersionForType for $type {} )*
84        )+
85
86        pub fn get_type_fingerprints(version: Version) -> BTreeMap<String, String> {
87            let mut map = BTreeMap::new();
88            $(
89                let fingerprint = {
90                    let mut fp = None;
91                    const FINGERPRINTS: &[(u32, fn() -> String)] = &[
92                        ($latest, <$latest_type as fprint::TypeFingerprint>::fingerprint),
93                        $( ($major, <$type as fprint::TypeFingerprint>::fingerprint) ),*
94                    ];
95                    for (major, type_fp) in FINGERPRINTS {
96                        if version.major >= *major {
97                            fp = Some(type_fp());
98                            break;
99                        }
100                    }
101                    fp
102                };
103                if let Some(fp) = fingerprint {
104                    map.insert(stringify!($name).to_string(), fp.to_string());
105                }
106            )+
107            map
108        }
109    };
110}
111
112versioned_types! {
113    AllocatorInfo {
114        32.. => AllocatorInfoV32,
115    }
116    AllocatorKey {
117        32.. => AllocatorKeyV32,
118    }
119    AllocatorValue {
120        32.. => AllocatorValueV32,
121    }
122    EncryptedMutations {
123        49.. => EncryptedMutationsV49,
124        40.. => EncryptedMutationsV40,
125    }
126    FsverityMetadata {
127        50.. => FsverityMetadataV50,
128        33.. => FsverityMetadataV33,
129    }
130    JournalRecord {
131        50.. => JournalRecordV50,
132        49.. => JournalRecordV49,
133        47.. => JournalRecordV47,
134        46.. => JournalRecordV46,
135        43.. => JournalRecordV43,
136        42.. => JournalRecordV42,
137        41.. => JournalRecordV41,
138        40.. => JournalRecordV40,
139    }
140    Mutation {
141        50.. => MutationV50,
142        49.. => MutationV49,
143        47.. => MutationV47,
144        46.. => MutationV46,
145        43.. => MutationV43,
146        41.. => MutationV41,
147        40.. => MutationV40,
148    }
149    ObjectKey {
150        43.. => ObjectKeyV43,
151        40.. => ObjectKeyV40,
152    }
153    ObjectValue {
154        50.. => ObjectValueV50,
155        49.. => ObjectValueV49,
156        47.. => ObjectValueV47,
157        46.. => ObjectValueV46,
158        41.. => ObjectValueV41,
159        40.. => ObjectValueV40,
160    }
161    PersistentLayerHeader {
162        39.. => PersistentLayerHeaderV39,
163    }
164    PersistentLayerInfo {
165        39.. => PersistentLayerInfoV39,
166    }
167    StoreInfo {
168        52.. => StoreInfoV52,
169        49.. => StoreInfoV49,
170        40.. => StoreInfoV40,
171    }
172    SuperBlockHeader {
173        32.. => SuperBlockHeaderV32,
174    }
175    SuperBlockRecord {
176        50.. => SuperBlockRecordV50,
177        49.. => SuperBlockRecordV49,
178        47.. => SuperBlockRecordV47,
179        46.. => SuperBlockRecordV46,
180        43.. => SuperBlockRecordV43,
181        41.. => SuperBlockRecordV41,
182        40.. => SuperBlockRecordV40,
183    }
184}