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, ObjectKindV59,
11    ObjectValueV59,
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(ObjectKindV59)]
45#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
46pub enum ObjectKindV54 {
47    File {
48        refs: u64,
49    },
50    Directory {
51        sub_dirs: u64,
52        dir_type: DirTypeV54,
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
67fn reject_legacy_key<'de, D: Deserializer<'de>>(_: D) -> Result<fxfs_crypto::FxfsKey, D::Error> {
68    Err(SerdeError::custom("LegacyFxfs keys are no longer supported"))
69}
70
71#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TypeFingerprint)]
72#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
73pub enum EncryptionKeyV56 {
74    LegacyFxfs(#[serde(deserialize_with = "reject_legacy_key")] fxfs_crypto::FxfsKey),
75    FscryptInoLblk32File { key_identifier: [u8; 16] },
76    FscryptInoLblk32Dir { key_identifier: [u8; 16], nonce: [u8; 16] },
77    Fxfs(fxfs_crypto::FxfsKey),
78}
79
80impl From<EncryptionKeyV56> for EncryptionKeyV59 {
81    fn from(old: EncryptionKeyV56) -> Self {
82        match old {
83            EncryptionKeyV56::LegacyFxfs(key) => EncryptionKeyV59::LegacyFxfs(key),
84            EncryptionKeyV56::FscryptInoLblk32File { key_identifier } => {
85                EncryptionKeyV59::FscryptInoLblk32File { key_identifier }
86            }
87            EncryptionKeyV56::FscryptInoLblk32Dir { key_identifier, nonce } => {
88                EncryptionKeyV59::FscryptInoLblk32Dir { key_identifier, nonce }
89            }
90            EncryptionKeyV56::Fxfs(key) => EncryptionKeyV59::Fxfs(key),
91        }
92    }
93}
94
95#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, TypeFingerprint)]
96#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
97pub struct EncryptionKeysV56(Vec<(u64, EncryptionKeyV56)>);
98
99impl From<EncryptionKeysV56> for EncryptionKeysV59 {
100    fn from(old: EncryptionKeysV56) -> Self {
101        Self(old.0.into_iter().map(|(id, key)| (id, key.into())).collect())
102    }
103}
104
105#[derive(Migrate, Clone, Debug, PartialEq, Serialize, Deserialize, TypeFingerprint, Versioned)]
106#[migrate_to_version(ObjectValueV59)]
107#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
108pub enum ObjectValueV56 {
109    None,
110    Some,
111    Object { kind: ObjectKindV54, attributes: ObjectAttributesV49 },
112    Keys(EncryptionKeysV56),
113    Attribute { size: u64, has_overwrite_extents: bool },
114    Extent(ExtentValueV38),
115    Child(ChildValue),
116    Trim,
117    BytesAndNodes { bytes: i64, nodes: i64 },
118    ExtendedAttribute(ExtendedAttributeValueV32),
119    VerifiedAttribute { size: u64, fsverity_metadata: FsverityMetadataV50 },
120}
121
122pub type ObjectItemV56 = Item<ObjectKeyV54, ObjectValueV56>;
123
124impl From<ObjectItemV56> for super::ObjectItemV59 {
125    fn from(item: ObjectItemV56) -> Self {
126        Self { key: item.key, value: item.value.into() }
127    }
128}