Skip to main content

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