Skip to main content

fxfs/object_store/object_record/
legacy.rs

1// Copyright 2025 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//! When types in `object_record` are versioned, legacy definitions and migration
6//! implementations should be placed in this module.
7
8use super::{
9    ChildValue, DirTypeV59, EncryptionKeyV59, EncryptionKeysV59, ExtendedAttributeValueV32,
10    ExtentValueV38, FsverityMetadataV50, Item, ObjectAttributesV49, ObjectKeyV54, ObjectKindV62,
11    ObjectValueV62,
12};
13use crate::serialized_types::{Migrate, Versioned, migrate_to_version};
14use fprint::TypeFingerprint;
15use fxfs_crypto::WrappingKeyId;
16use serde::de::Error as SerdeError;
17use serde::{Deserialize, Deserializer, Serialize};
18
19#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, TypeFingerprint)]
20#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
21pub enum DirTypeV54 {
22    Normal,
23    Encrypted(WrappingKeyId),
24    LegacyCasefold,
25    Casefold,
26    EncryptedCasefold(WrappingKeyId),
27}
28
29impl From<DirTypeV54> for DirTypeV59 {
30    fn from(old: DirTypeV54) -> Self {
31        match old {
32            DirTypeV54::Normal => DirTypeV59::Normal,
33            DirTypeV54::Encrypted(wrapping_key_id) => DirTypeV59::Encrypted(wrapping_key_id.into()),
34            DirTypeV54::LegacyCasefold => DirTypeV59::LegacyCasefold,
35            DirTypeV54::Casefold => DirTypeV59::Casefold,
36            DirTypeV54::EncryptedCasefold(wrapping_key_id) => {
37                DirTypeV59::EncryptedCasefold(wrapping_key_id.into())
38            }
39        }
40    }
41}
42
43#[derive(Migrate, Clone, Debug, Serialize, Deserialize, PartialEq, TypeFingerprint)]
44#[migrate_to_version(ObjectKindV62)]
45#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
46pub enum ObjectKindV59 {
47    File {
48        refs: u64,
49    },
50    Directory {
51        sub_dirs: u64,
52        dir_type: DirTypeV59,
53    },
54    Graveyard,
55    Symlink {
56        refs: u64,
57        #[serde(with = "crate::zerocopy_serialization")]
58        link: Box<[u8]>,
59    },
60    EncryptedSymlink {
61        refs: u64,
62        #[serde(with = "crate::zerocopy_serialization")]
63        link: Box<[u8]>,
64    },
65}
66
67#[derive(Migrate, Clone, Debug, Serialize, Deserialize, PartialEq, TypeFingerprint)]
68#[migrate_to_version(ObjectKindV59)]
69#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
70pub enum ObjectKindV54 {
71    File {
72        refs: u64,
73    },
74    Directory {
75        sub_dirs: u64,
76        dir_type: DirTypeV54,
77    },
78    Graveyard,
79    Symlink {
80        refs: u64,
81        #[serde(with = "crate::zerocopy_serialization")]
82        link: Box<[u8]>,
83    },
84    EncryptedSymlink {
85        refs: u64,
86        #[serde(with = "crate::zerocopy_serialization")]
87        link: Box<[u8]>,
88    },
89}
90
91fn reject_legacy_key<'de, D: Deserializer<'de>>(_: D) -> Result<fxfs_crypto::FxfsKey, D::Error> {
92    Err(SerdeError::custom("LegacyFxfs keys are no longer supported"))
93}
94
95#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TypeFingerprint)]
96#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
97pub enum EncryptionKeyV56 {
98    LegacyFxfs(#[serde(deserialize_with = "reject_legacy_key")] fxfs_crypto::FxfsKey),
99    FscryptInoLblk32File { key_identifier: [u8; 16] },
100    FscryptInoLblk32Dir { key_identifier: [u8; 16], nonce: [u8; 16] },
101    Fxfs(fxfs_crypto::FxfsKey),
102}
103
104impl From<EncryptionKeyV56> for EncryptionKeyV59 {
105    fn from(old: EncryptionKeyV56) -> Self {
106        match old {
107            EncryptionKeyV56::LegacyFxfs(key) => EncryptionKeyV59::LegacyFxfs(key),
108            EncryptionKeyV56::FscryptInoLblk32File { key_identifier } => {
109                EncryptionKeyV59::FscryptInoLblk32File { key_identifier }
110            }
111            EncryptionKeyV56::FscryptInoLblk32Dir { key_identifier, nonce } => {
112                EncryptionKeyV59::FscryptInoLblk32Dir { key_identifier, nonce }
113            }
114            EncryptionKeyV56::Fxfs(key) => EncryptionKeyV59::Fxfs(key),
115        }
116    }
117}
118
119#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, TypeFingerprint)]
120#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
121pub struct EncryptionKeysV56(Vec<(u64, EncryptionKeyV56)>);
122
123impl From<EncryptionKeysV56> for EncryptionKeysV59 {
124    fn from(old: EncryptionKeysV56) -> Self {
125        Self(old.0.into_iter().map(|(id, key)| (id, key.into())).collect())
126    }
127}
128
129#[derive(Migrate, Clone, Debug, PartialEq, Serialize, Deserialize, TypeFingerprint, Versioned)]
130#[migrate_to_version(ObjectValueV62)]
131#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
132pub enum ObjectValueV59 {
133    None,
134    Some,
135    Object { kind: ObjectKindV59, attributes: ObjectAttributesV49 },
136    Keys(EncryptionKeysV59),
137    Attribute { size: u64, has_overwrite_extents: bool },
138    Extent(ExtentValueV38),
139    Child(ChildValue),
140    Trim,
141    BytesAndNodes { bytes: i64, nodes: i64 },
142    ExtendedAttribute(ExtendedAttributeValueV32),
143    VerifiedAttribute { size: u64, fsverity_metadata: FsverityMetadataV50 },
144}
145
146pub type ObjectItemV59 = Item<ObjectKeyV54, ObjectValueV59>;
147
148impl From<ObjectItemV59> for super::ObjectItemV62 {
149    fn from(item: ObjectItemV59) -> Self {
150        Self { key: item.key, value: item.value.into() }
151    }
152}
153
154#[derive(Migrate, Clone, Debug, PartialEq, Serialize, Deserialize, TypeFingerprint, Versioned)]
155#[migrate_to_version(ObjectValueV59)]
156#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
157pub enum ObjectValueV56 {
158    None,
159    Some,
160    Object { kind: ObjectKindV54, attributes: ObjectAttributesV49 },
161    Keys(EncryptionKeysV56),
162    Attribute { size: u64, has_overwrite_extents: bool },
163    Extent(ExtentValueV38),
164    Child(ChildValue),
165    Trim,
166    BytesAndNodes { bytes: i64, nodes: i64 },
167    ExtendedAttribute(ExtendedAttributeValueV32),
168    VerifiedAttribute { size: u64, fsverity_metadata: FsverityMetadataV50 },
169}
170
171pub type ObjectItemV56 = Item<ObjectKeyV54, ObjectValueV56>;
172
173impl From<ObjectItemV56> for ObjectItemV59 {
174    fn from(item: ObjectItemV56) -> Self {
175        Self { key: item.key, value: item.value.into() }
176    }
177}