1use crate::checksum::Checksums;
7use crate::lsm_tree::types::{
8 FuzzyHash, Item, ItemRef, LayerKey, MergeType, OrdLowerBound, OrdUpperBound, RangeKey,
9 SortByU64, Value,
10};
11use crate::object_store::extent_record::{
12 ExtentKey, ExtentKeyPartitionIterator, ExtentKeyV32, ExtentValue, ExtentValueV32,
13 ExtentValueV37, ExtentValueV38,
14};
15use crate::serialized_types::{migrate_nodefault, migrate_to_version, Migrate, Versioned};
16use fprint::TypeFingerprint;
17use fxfs_crypto::{WrappedKeysV32, WrappedKeysV40};
18use fxfs_unicode::CasefoldString;
19use rustc_hash::FxHasher;
20use serde::{Deserialize, Serialize};
21use std::default::Default;
22use std::hash::{Hash, Hasher as _};
23use std::time::{Duration, SystemTime, UNIX_EPOCH};
24
25pub type ObjectDescriptor = ObjectDescriptorV32;
27
28#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, TypeFingerprint)]
29#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
30pub enum ObjectDescriptorV32 {
31 File,
33 Directory,
35 Volume,
37 Symlink,
39}
40
41pub type ProjectProperty = ProjectPropertyV32;
43
44#[derive(
45 Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize, TypeFingerprint,
46)]
47#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
48pub enum ProjectPropertyV32 {
49 Limit,
51 Usage,
53}
54
55pub type ObjectKeyData = ObjectKeyDataV43;
56
57#[derive(
58 Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize, TypeFingerprint,
59)]
60#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
61pub enum ObjectKeyDataV43 {
62 Object,
65 Keys,
67 Attribute(u64, AttributeKeyV32),
69 Child { name: String },
71 GraveyardEntry { object_id: u64 },
73 Project { project_id: u64, property: ProjectPropertyV32 },
77 ExtendedAttribute { name: Vec<u8> },
80 GraveyardAttributeEntry { object_id: u64, attribute_id: u64 },
82 EncryptedChild { casefold_hash: u32, name: Vec<u8> },
88 CasefoldChild { name: CasefoldString },
91}
92
93impl From<ObjectKeyDataV40> for ObjectKeyDataV43 {
94 fn from(item: ObjectKeyDataV40) -> Self {
95 match item {
96 ObjectKeyDataV40::Object => Self::Object,
97 ObjectKeyDataV40::Keys => Self::Keys,
98 ObjectKeyDataV40::Attribute(a, b) => Self::Attribute(a, b),
99 ObjectKeyDataV40::Child { name } => Self::Child { name },
100 ObjectKeyDataV40::GraveyardEntry { object_id } => Self::GraveyardEntry { object_id },
101 ObjectKeyDataV40::Project { project_id, property } => {
102 Self::Project { project_id, property }
103 }
104 ObjectKeyDataV40::ExtendedAttribute { name } => Self::ExtendedAttribute { name },
105 ObjectKeyDataV40::GraveyardAttributeEntry { object_id, attribute_id } => {
106 Self::GraveyardAttributeEntry { object_id, attribute_id }
107 }
108 ObjectKeyDataV40::EncryptedChild { name } => {
109 Self::EncryptedChild { casefold_hash: 0, name }
110 }
111 ObjectKeyDataV40::CasefoldChild { name } => Self::CasefoldChild { name },
112 }
113 }
114}
115
116#[derive(Serialize, Deserialize, TypeFingerprint)]
117#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
118pub enum ObjectKeyDataV40 {
119 Object,
120 Keys,
121 Attribute(u64, AttributeKeyV32),
122 Child { name: String },
123 GraveyardEntry { object_id: u64 },
124 Project { project_id: u64, property: ProjectPropertyV32 },
125 ExtendedAttribute { name: Vec<u8> },
126 GraveyardAttributeEntry { object_id: u64, attribute_id: u64 },
127 EncryptedChild { name: Vec<u8> },
128 CasefoldChild { name: CasefoldString },
129}
130
131#[derive(Migrate, Serialize, Deserialize, TypeFingerprint)]
132#[migrate_to_version(ObjectKeyDataV40)]
133pub enum ObjectKeyDataV32 {
134 Object,
135 Keys,
136 Attribute(u64, AttributeKeyV32),
137 Child { name: String },
138 GraveyardEntry { object_id: u64 },
139 Project { project_id: u64, property: ProjectPropertyV32 },
140 ExtendedAttribute { name: Vec<u8> },
141 GraveyardAttributeEntry { object_id: u64, attribute_id: u64 },
142}
143
144pub type AttributeKey = AttributeKeyV32;
145
146#[derive(
147 Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize, TypeFingerprint,
148)]
149#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
150pub enum AttributeKeyV32 {
151 Attribute,
153 Extent(ExtentKeyV32),
154}
155
156pub type ObjectKey = ObjectKeyV43;
158
159#[derive(
160 Clone,
161 Debug,
162 Eq,
163 Ord,
164 Hash,
165 PartialEq,
166 PartialOrd,
167 Serialize,
168 Deserialize,
169 TypeFingerprint,
170 Versioned,
171)]
172#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
173pub struct ObjectKeyV43 {
174 pub object_id: u64,
176 pub data: ObjectKeyDataV43,
178}
179
180#[derive(Migrate, Serialize, Deserialize, TypeFingerprint, Versioned)]
181#[migrate_to_version(ObjectKeyV43)]
182#[migrate_nodefault]
183pub struct ObjectKeyV40 {
184 pub object_id: u64,
185 pub data: ObjectKeyDataV40,
186}
187#[derive(Migrate, Serialize, Deserialize, TypeFingerprint, Versioned)]
188#[migrate_to_version(ObjectKeyV40)]
189#[migrate_nodefault]
190pub struct ObjectKeyV32 {
191 pub object_id: u64,
192 pub data: ObjectKeyDataV32,
193}
194
195impl SortByU64 for ObjectKey {
196 fn get_leading_u64(&self) -> u64 {
197 self.object_id
198 }
199}
200
201impl ObjectKey {
202 pub fn object(object_id: u64) -> Self {
204 Self { object_id: object_id, data: ObjectKeyData::Object }
205 }
206
207 pub fn keys(object_id: u64) -> Self {
209 Self { object_id, data: ObjectKeyData::Keys }
210 }
211
212 pub fn attribute(object_id: u64, attribute_id: u64, key: AttributeKey) -> Self {
214 Self { object_id, data: ObjectKeyData::Attribute(attribute_id, key) }
215 }
216
217 pub fn extent(object_id: u64, attribute_id: u64, range: std::ops::Range<u64>) -> Self {
219 Self {
220 object_id,
221 data: ObjectKeyData::Attribute(
222 attribute_id,
223 AttributeKey::Extent(ExtentKey::new(range)),
224 ),
225 }
226 }
227
228 pub fn from_extent(object_id: u64, attribute_id: u64, extent: ExtentKey) -> Self {
230 Self {
231 object_id,
232 data: ObjectKeyData::Attribute(attribute_id, AttributeKey::Extent(extent)),
233 }
234 }
235
236 pub fn child(object_id: u64, name: &str, casefold: bool) -> Self {
238 if casefold {
239 Self { object_id, data: ObjectKeyData::CasefoldChild { name: name.into() } }
240 } else {
241 Self { object_id, data: ObjectKeyData::Child { name: name.into() } }
242 }
243 }
244
245 pub fn encrypted_child(object_id: u64, name: Vec<u8>, casefold_hash: u32) -> Self {
247 Self { object_id, data: ObjectKeyData::EncryptedChild { casefold_hash, name } }
248 }
249
250 pub fn graveyard_entry(graveyard_object_id: u64, object_id: u64) -> Self {
252 Self { object_id: graveyard_object_id, data: ObjectKeyData::GraveyardEntry { object_id } }
253 }
254
255 pub fn graveyard_attribute_entry(
257 graveyard_object_id: u64,
258 object_id: u64,
259 attribute_id: u64,
260 ) -> Self {
261 Self {
262 object_id: graveyard_object_id,
263 data: ObjectKeyData::GraveyardAttributeEntry { object_id, attribute_id },
264 }
265 }
266
267 pub fn project_limit(object_id: u64, project_id: u64) -> Self {
269 Self {
270 object_id,
271 data: ObjectKeyData::Project { project_id, property: ProjectProperty::Limit },
272 }
273 }
274
275 pub fn project_usage(object_id: u64, project_id: u64) -> Self {
277 Self {
278 object_id,
279 data: ObjectKeyData::Project { project_id, property: ProjectProperty::Usage },
280 }
281 }
282
283 pub fn extended_attribute(object_id: u64, name: Vec<u8>) -> Self {
284 Self { object_id, data: ObjectKeyData::ExtendedAttribute { name } }
285 }
286
287 pub fn key_for_merge_into(&self) -> Self {
290 if let Self {
291 object_id,
292 data: ObjectKeyData::Attribute(attribute_id, AttributeKey::Extent(e)),
293 } = self
294 {
295 Self::attribute(*object_id, *attribute_id, AttributeKey::Extent(e.key_for_merge_into()))
296 } else {
297 self.clone()
298 }
299 }
300}
301
302impl OrdUpperBound for ObjectKey {
303 fn cmp_upper_bound(&self, other: &ObjectKey) -> std::cmp::Ordering {
304 self.object_id.cmp(&other.object_id).then_with(|| match (&self.data, &other.data) {
305 (
306 ObjectKeyData::Attribute(left_attr_id, AttributeKey::Extent(ref left_extent)),
307 ObjectKeyData::Attribute(right_attr_id, AttributeKey::Extent(ref right_extent)),
308 ) => left_attr_id.cmp(right_attr_id).then(left_extent.cmp_upper_bound(right_extent)),
309 _ => self.data.cmp(&other.data),
310 })
311 }
312}
313
314impl OrdLowerBound for ObjectKey {
315 fn cmp_lower_bound(&self, other: &ObjectKey) -> std::cmp::Ordering {
316 self.object_id.cmp(&other.object_id).then_with(|| match (&self.data, &other.data) {
317 (
318 ObjectKeyData::Attribute(left_attr_id, AttributeKey::Extent(ref left_extent)),
319 ObjectKeyData::Attribute(right_attr_id, AttributeKey::Extent(ref right_extent)),
320 ) => left_attr_id.cmp(right_attr_id).then(left_extent.cmp_lower_bound(right_extent)),
321 _ => self.data.cmp(&other.data),
322 })
323 }
324}
325
326impl LayerKey for ObjectKey {
327 fn merge_type(&self) -> MergeType {
328 match self.data {
331 ObjectKeyData::Object
332 | ObjectKeyData::Keys
333 | ObjectKeyData::Attribute(..)
334 | ObjectKeyData::Child { .. }
335 | ObjectKeyData::EncryptedChild { .. }
336 | ObjectKeyData::CasefoldChild { .. }
337 | ObjectKeyData::GraveyardEntry { .. }
338 | ObjectKeyData::GraveyardAttributeEntry { .. }
339 | ObjectKeyData::Project { property: ProjectProperty::Limit, .. }
340 | ObjectKeyData::ExtendedAttribute { .. } => MergeType::OptimizedMerge,
341 ObjectKeyData::Project { property: ProjectProperty::Usage, .. } => MergeType::FullMerge,
342 }
343 }
344
345 fn next_key(&self) -> Option<Self> {
346 match self.data {
347 ObjectKeyData::Attribute(_, AttributeKey::Extent(_)) => {
348 let mut key = self.clone();
349 if let ObjectKey {
350 data: ObjectKeyData::Attribute(_, AttributeKey::Extent(ExtentKey { range })),
351 ..
352 } = &mut key
353 {
354 *range = range.end..range.end + 1;
358 }
359 Some(key)
360 }
361 _ => None,
362 }
363 }
364
365 fn search_key(&self) -> Self {
366 if let Self {
367 object_id,
368 data: ObjectKeyData::Attribute(attribute_id, AttributeKey::Extent(e)),
369 } = self
370 {
371 Self::attribute(*object_id, *attribute_id, AttributeKey::Extent(e.search_key()))
372 } else {
373 self.clone()
374 }
375 }
376}
377
378impl RangeKey for ObjectKey {
379 fn overlaps(&self, other: &Self) -> bool {
380 if self.object_id != other.object_id {
381 return false;
382 }
383 match (&self.data, &other.data) {
384 (
385 ObjectKeyData::Attribute(left_attr_id, AttributeKey::Extent(left_key)),
386 ObjectKeyData::Attribute(right_attr_id, AttributeKey::Extent(right_key)),
387 ) if *left_attr_id == *right_attr_id => {
388 left_key.range.end > right_key.range.start
389 && left_key.range.start < right_key.range.end
390 }
391 (a, b) => a == b,
392 }
393 }
394}
395
396pub enum ObjectKeyFuzzyHashIterator {
397 ExtentKey(u64, u64, ExtentKeyPartitionIterator),
398 NotExtentKey(Option<u64>),
399}
400
401impl Iterator for ObjectKeyFuzzyHashIterator {
402 type Item = u64;
403
404 fn next(&mut self) -> Option<Self::Item> {
405 match self {
406 Self::ExtentKey(oid, attr_id, extent_keys) => extent_keys.next().map(|range| {
407 let mut hasher = FxHasher::default();
408 ObjectKey::extent(*oid, *attr_id, range).hash(&mut hasher);
409 hasher.finish()
410 }),
411 Self::NotExtentKey(hash) => hash.take(),
412 }
413 }
414}
415
416impl FuzzyHash for ObjectKey {
417 type Iter = ObjectKeyFuzzyHashIterator;
418
419 fn fuzzy_hash(&self) -> Self::Iter {
420 match &self.data {
421 ObjectKeyData::Attribute(attr_id, AttributeKey::Extent(extent)) => {
422 ObjectKeyFuzzyHashIterator::ExtentKey(
423 self.object_id,
424 *attr_id,
425 extent.fuzzy_hash_partition(),
426 )
427 }
428 _ => {
429 let mut hasher = FxHasher::default();
430 self.hash(&mut hasher);
431 ObjectKeyFuzzyHashIterator::NotExtentKey(Some(hasher.finish()))
432 }
433 }
434 }
435}
436
437pub type Timestamp = TimestampV32;
439
440#[derive(
441 Copy,
442 Clone,
443 Debug,
444 Default,
445 Eq,
446 PartialEq,
447 Ord,
448 PartialOrd,
449 Serialize,
450 Deserialize,
451 TypeFingerprint,
452)]
453#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
454pub struct TimestampV32 {
455 pub secs: u64,
456 pub nanos: u32,
457}
458
459impl Timestamp {
460 const NSEC_PER_SEC: u64 = 1_000_000_000;
461
462 pub fn now() -> Self {
463 SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or(Duration::ZERO).into()
464 }
465
466 pub const fn zero() -> Self {
467 Self { secs: 0, nanos: 0 }
468 }
469
470 pub const fn from_nanos(nanos: u64) -> Self {
471 let subsec_nanos = (nanos % Self::NSEC_PER_SEC) as u32;
472 Self { secs: nanos / Self::NSEC_PER_SEC, nanos: subsec_nanos }
473 }
474
475 pub fn as_nanos(&self) -> u64 {
476 Self::NSEC_PER_SEC
477 .checked_mul(self.secs)
478 .and_then(|val| val.checked_add(self.nanos as u64))
479 .unwrap_or(0u64)
480 }
481}
482
483impl From<std::time::Duration> for Timestamp {
484 fn from(duration: std::time::Duration) -> Timestamp {
485 Timestamp { secs: duration.as_secs(), nanos: duration.subsec_nanos() }
486 }
487}
488
489impl From<Timestamp> for std::time::Duration {
490 fn from(timestamp: Timestamp) -> std::time::Duration {
491 Duration::new(timestamp.secs, timestamp.nanos)
492 }
493}
494
495pub type ObjectKind = ObjectKindV41;
496
497#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, TypeFingerprint)]
498#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
499pub enum ObjectKindV41 {
500 File {
501 refs: u64,
503 },
504 Directory {
505 sub_dirs: u64,
507 wrapping_key_id: Option<u128>,
510 casefold: bool,
513 },
514 Graveyard,
515 Symlink {
516 refs: u64,
518 link: Vec<u8>,
521 },
522}
523
524#[derive(Debug, Serialize, Deserialize, PartialEq, TypeFingerprint)]
525pub enum ObjectKindV40 {
526 File { refs: u64, has_overwrite_extents: bool },
527 Directory { sub_dirs: u64, wrapping_key_id: Option<u128>, casefold: bool },
528 Graveyard,
529 Symlink { refs: u64, link: Vec<u8> },
530}
531
532impl From<ObjectKindV40> for ObjectKindV41 {
533 fn from(value: ObjectKindV40) -> Self {
534 match value {
535 ObjectKindV40::File { refs, .. } => ObjectKindV41::File { refs },
537 ObjectKindV40::Directory { sub_dirs, wrapping_key_id, casefold } => {
538 ObjectKindV41::Directory { sub_dirs, wrapping_key_id, casefold }
539 }
540 ObjectKindV40::Graveyard => ObjectKindV41::Graveyard,
541 ObjectKindV40::Symlink { refs, link } => ObjectKindV41::Symlink { refs, link },
542 }
543 }
544}
545
546#[derive(Debug, Serialize, Deserialize, PartialEq, TypeFingerprint)]
547pub enum ObjectKindV38 {
548 File { refs: u64, has_overwrite_extents: bool },
549 Directory { sub_dirs: u64 },
550 Graveyard,
551 Symlink { refs: u64, link: Vec<u8> },
552}
553
554impl From<ObjectKindV38> for ObjectKindV40 {
555 fn from(value: ObjectKindV38) -> Self {
556 match value {
557 ObjectKindV38::File { refs, has_overwrite_extents } => {
558 ObjectKindV40::File { refs, has_overwrite_extents }
559 }
560 ObjectKindV38::Directory { sub_dirs } => {
561 ObjectKindV40::Directory { sub_dirs, wrapping_key_id: None, casefold: false }
562 }
563 ObjectKindV38::Graveyard => ObjectKindV40::Graveyard,
564 ObjectKindV38::Symlink { refs, link } => ObjectKindV40::Symlink { refs, link },
565 }
566 }
567}
568
569#[derive(Debug, Deserialize, Serialize, TypeFingerprint)]
570pub enum ObjectKindV32 {
571 File { refs: u64 },
572 Directory { sub_dirs: u64 },
573 Graveyard,
574 Symlink { refs: u64, link: Vec<u8> },
575}
576
577impl From<ObjectKindV32> for ObjectKindV38 {
578 fn from(value: ObjectKindV32) -> Self {
579 match value {
580 ObjectKindV32::File { refs } => {
583 ObjectKindV38::File { refs, has_overwrite_extents: false }
584 }
585 ObjectKindV32::Directory { sub_dirs } => ObjectKindV38::Directory { sub_dirs },
586 ObjectKindV32::Graveyard => ObjectKindV38::Graveyard,
587 ObjectKindV32::Symlink { refs, link } => ObjectKindV38::Symlink { refs, link },
588 }
589 }
590}
591
592pub type EncryptionKeys = EncryptionKeysV40;
593
594#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, TypeFingerprint)]
595pub enum EncryptionKeysV40 {
596 AES256XTS(WrappedKeysV40),
597}
598
599#[derive(Migrate, Serialize, Deserialize, TypeFingerprint)]
600pub enum EncryptionKeysV32 {
601 AES256XTS(WrappedKeysV32),
602}
603
604#[cfg(fuzz)]
605impl<'a> arbitrary::Arbitrary<'a> for EncryptionKeys {
606 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
607 <u8>::arbitrary(u).and_then(|count| {
608 let mut keys = vec![];
609 for _ in 0..count {
610 keys.push(<(u64, u128)>::arbitrary(u).map(|(id, wrapping_key_id)| {
611 (
612 id,
613 fxfs_crypto::WrappedKey {
614 wrapping_key_id,
615 key: fxfs_crypto::WrappedKeyBytes::default(),
617 },
618 )
619 })?);
620 }
621 Ok(EncryptionKeys::AES256XTS(fxfs_crypto::WrappedKeys::from(keys)))
622 })
623 }
624}
625pub type PosixAttributes = PosixAttributesV32;
628
629#[derive(Clone, Debug, Copy, Default, Serialize, Deserialize, PartialEq, TypeFingerprint)]
630#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
631pub struct PosixAttributesV32 {
632 pub mode: u32,
634 pub uid: u32,
636 pub gid: u32,
638 pub rdev: u64,
640}
641
642pub type ObjectAttributes = ObjectAttributesV32;
646
647#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, TypeFingerprint)]
648#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
649pub struct ObjectAttributesV32 {
650 pub creation_time: TimestampV32,
652 pub modification_time: TimestampV32,
654 pub project_id: u64,
656 pub posix_attributes: Option<PosixAttributesV32>,
658 pub allocated_size: u64,
660 pub access_time: TimestampV32,
662 pub change_time: TimestampV32,
664}
665
666pub type ExtendedAttributeValue = ExtendedAttributeValueV32;
667
668#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, TypeFingerprint)]
669#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
670pub enum ExtendedAttributeValueV32 {
671 Inline(Vec<u8>),
674 AttributeId(u64),
677}
678
679pub type ChildValue = ChildValueV32;
681
682#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, TypeFingerprint)]
683#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
684pub struct ChildValueV32 {
685 pub object_id: u64,
687 pub object_descriptor: ObjectDescriptorV32,
689}
690
691pub type RootDigest = RootDigestV33;
692
693#[derive(
694 Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize, TypeFingerprint,
695)]
696#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
697pub enum RootDigestV33 {
698 Sha256([u8; 32]),
699 Sha512(Vec<u8>),
700}
701
702pub type FsverityMetadata = FsverityMetadataV33;
703
704#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, TypeFingerprint, Versioned)]
705#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
706pub struct FsverityMetadataV33 {
707 pub root_digest: RootDigestV33,
708 pub salt: Vec<u8>,
709}
710
711pub type ObjectValue = ObjectValueV41;
715impl Value for ObjectValue {
716 const DELETED_MARKER: Self = Self::None;
717}
718
719#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, TypeFingerprint, Versioned)]
720#[cfg_attr(fuzz, derive(arbitrary::Arbitrary))]
721pub enum ObjectValueV41 {
722 None,
726 Some,
729 Object { kind: ObjectKindV41, attributes: ObjectAttributesV32 },
731 Keys(EncryptionKeysV40),
733 Attribute { size: u64, has_overwrite_extents: bool },
735 Extent(ExtentValueV38),
737 Child(ChildValueV32),
739 Trim,
743 BytesAndNodes { bytes: i64, nodes: i64 },
745 ExtendedAttribute(ExtendedAttributeValueV32),
748 VerifiedAttribute { size: u64, fsverity_metadata: FsverityMetadataV33 },
751}
752
753impl From<ObjectValueV40> for ObjectValueV41 {
754 fn from(value: ObjectValueV40) -> Self {
755 match value {
756 ObjectValueV40::None => ObjectValueV41::None,
757 ObjectValueV40::Some => ObjectValueV41::Some,
758 ObjectValueV40::Object { kind, attributes } => {
759 ObjectValueV41::Object { kind: kind.into(), attributes }
760 }
761 ObjectValueV40::Keys(keys) => ObjectValueV41::Keys(keys),
762 ObjectValueV40::Attribute { size } => {
763 ObjectValueV41::Attribute { size, has_overwrite_extents: false }
764 }
765 ObjectValueV40::Extent(extent_value) => ObjectValueV41::Extent(extent_value),
766 ObjectValueV40::Child(child) => ObjectValueV41::Child(child),
767 ObjectValueV40::Trim => ObjectValueV41::Trim,
768 ObjectValueV40::BytesAndNodes { bytes, nodes } => {
769 ObjectValueV41::BytesAndNodes { bytes, nodes }
770 }
771 ObjectValueV40::ExtendedAttribute(xattr) => ObjectValueV41::ExtendedAttribute(xattr),
772 ObjectValueV40::VerifiedAttribute { size, fsverity_metadata } => {
773 ObjectValueV41::VerifiedAttribute { size, fsverity_metadata }
774 }
775 }
776 }
777}
778
779#[derive(Serialize, Deserialize, TypeFingerprint, Versioned)]
780pub enum ObjectValueV40 {
781 None,
782 Some,
783 Object { kind: ObjectKindV40, attributes: ObjectAttributesV32 },
784 Keys(EncryptionKeysV40),
785 Attribute { size: u64 },
786 Extent(ExtentValueV38),
787 Child(ChildValueV32),
788 Trim,
789 BytesAndNodes { bytes: i64, nodes: i64 },
790 ExtendedAttribute(ExtendedAttributeValueV32),
791 VerifiedAttribute { size: u64, fsverity_metadata: FsverityMetadataV33 },
792}
793
794#[derive(Migrate, Serialize, Deserialize, TypeFingerprint, Versioned)]
795#[migrate_to_version(ObjectValueV40)]
796pub enum ObjectValueV38 {
797 None,
798 Some,
799 Object { kind: ObjectKindV38, attributes: ObjectAttributesV32 },
800 Keys(EncryptionKeysV32),
801 Attribute { size: u64 },
802 Extent(ExtentValueV38),
803 Child(ChildValueV32),
804 Trim,
805 BytesAndNodes { bytes: i64, nodes: i64 },
806 ExtendedAttribute(ExtendedAttributeValueV32),
807 VerifiedAttribute { size: u64, fsverity_metadata: FsverityMetadataV33 },
808}
809
810#[derive(Migrate, Serialize, Deserialize, TypeFingerprint, Versioned)]
811#[migrate_to_version(ObjectValueV38)]
812pub enum ObjectValueV37 {
813 None,
814 Some,
815 Object { kind: ObjectKindV32, attributes: ObjectAttributesV32 },
816 Keys(EncryptionKeysV32),
817 Attribute { size: u64 },
818 Extent(ExtentValueV37),
819 Child(ChildValueV32),
820 Trim,
821 BytesAndNodes { bytes: i64, nodes: i64 },
822 ExtendedAttribute(ExtendedAttributeValueV32),
823 VerifiedAttribute { size: u64, fsverity_metadata: FsverityMetadataV33 },
824}
825
826#[derive(Serialize, Deserialize, Migrate, TypeFingerprint, Versioned)]
827#[migrate_to_version(ObjectValueV37)]
828pub enum ObjectValueV33 {
829 None,
830 Some,
831 Object { kind: ObjectKindV32, attributes: ObjectAttributesV32 },
832 Keys(EncryptionKeysV32),
833 Attribute { size: u64 },
834 Extent(ExtentValueV32),
835 Child(ChildValueV32),
836 Trim,
837 BytesAndNodes { bytes: i64, nodes: i64 },
838 ExtendedAttribute(ExtendedAttributeValueV32),
839 VerifiedAttribute { size: u64, fsverity_metadata: FsverityMetadataV33 },
840}
841
842#[derive(Deserialize, Migrate, Serialize, Versioned, TypeFingerprint)]
843#[migrate_to_version(ObjectValueV33)]
844pub enum ObjectValueV32 {
845 None,
846 Some,
847 Object { kind: ObjectKindV32, attributes: ObjectAttributesV32 },
848 Keys(EncryptionKeysV32),
849 Attribute { size: u64 },
850 Extent(ExtentValueV32),
851 Child(ChildValueV32),
852 Trim,
853 BytesAndNodes { bytes: i64, nodes: i64 },
854 ExtendedAttribute(ExtendedAttributeValueV32),
855}
856
857impl ObjectValue {
858 pub fn file(
860 refs: u64,
861 allocated_size: u64,
862 creation_time: Timestamp,
863 modification_time: Timestamp,
864 access_time: Timestamp,
865 change_time: Timestamp,
866 project_id: u64,
867 posix_attributes: Option<PosixAttributes>,
868 ) -> ObjectValue {
869 ObjectValue::Object {
870 kind: ObjectKind::File { refs },
871 attributes: ObjectAttributes {
872 creation_time,
873 modification_time,
874 project_id,
875 posix_attributes,
876 allocated_size,
877 access_time,
878 change_time,
879 },
880 }
881 }
882 pub fn keys(keys: EncryptionKeys) -> ObjectValue {
883 ObjectValue::Keys(keys)
884 }
885 pub fn attribute(size: u64, has_overwrite_extents: bool) -> ObjectValue {
887 ObjectValue::Attribute { size, has_overwrite_extents }
888 }
889 pub fn verified_attribute(size: u64, fsverity_metadata: FsverityMetadata) -> ObjectValue {
891 ObjectValue::VerifiedAttribute { size, fsverity_metadata }
892 }
893 pub fn extent(device_offset: u64, key_id: u64) -> ObjectValue {
895 ObjectValue::Extent(ExtentValue::new_raw(device_offset, key_id))
896 }
897 pub fn extent_with_checksum(
899 device_offset: u64,
900 checksum: Checksums,
901 key_id: u64,
902 ) -> ObjectValue {
903 ObjectValue::Extent(ExtentValue::with_checksum(device_offset, checksum, key_id))
904 }
905 pub fn deleted_extent() -> ObjectValue {
907 ObjectValue::Extent(ExtentValue::deleted_extent())
908 }
909 pub fn child(object_id: u64, object_descriptor: ObjectDescriptor) -> ObjectValue {
911 ObjectValue::Child(ChildValue { object_id, object_descriptor })
912 }
913 pub fn symlink(
915 link: impl Into<Vec<u8>>,
916 creation_time: Timestamp,
917 modification_time: Timestamp,
918 project_id: u64,
919 ) -> ObjectValue {
920 ObjectValue::Object {
921 kind: ObjectKind::Symlink { refs: 1, link: link.into() },
922 attributes: ObjectAttributes {
923 creation_time,
924 modification_time,
925 project_id,
926 ..Default::default()
927 },
928 }
929 }
930 pub fn inline_extended_attribute(value: impl Into<Vec<u8>>) -> ObjectValue {
931 ObjectValue::ExtendedAttribute(ExtendedAttributeValue::Inline(value.into()))
932 }
933 pub fn extended_attribute(attribute_id: u64) -> ObjectValue {
934 ObjectValue::ExtendedAttribute(ExtendedAttributeValue::AttributeId(attribute_id))
935 }
936}
937
938pub type ObjectItem = ObjectItemV43;
939pub type ObjectItemV43 = Item<ObjectKeyV43, ObjectValueV41>;
940pub type ObjectItemV41 = Item<ObjectKeyV40, ObjectValueV41>;
941pub type ObjectItemV40 = Item<ObjectKeyV40, ObjectValueV40>;
942
943impl From<ObjectItemV41> for ObjectItemV43 {
944 fn from(item: ObjectItemV41) -> Self {
945 Self { key: item.key.into(), value: item.value.into(), sequence: item.sequence }
946 }
947}
948impl From<ObjectItemV40> for ObjectItemV41 {
949 fn from(item: ObjectItemV40) -> Self {
950 Self { key: item.key.into(), value: item.value.into(), sequence: item.sequence }
951 }
952}
953
954impl ObjectItem {
955 pub fn is_tombstone(&self) -> bool {
956 matches!(
957 self,
958 Item {
959 key: ObjectKey { data: ObjectKeyData::Object, .. },
960 value: ObjectValue::None,
961 ..
962 }
963 )
964 }
965}
966
967impl<'a> From<ItemRef<'a, ObjectKey, ObjectValue>>
969 for Option<(u64, u64, &'a ExtentKey, &'a ExtentValue)>
970{
971 fn from(item: ItemRef<'a, ObjectKey, ObjectValue>) -> Self {
972 match item {
973 ItemRef {
974 key:
975 ObjectKey {
976 object_id,
977 data:
978 ObjectKeyData::Attribute(
979 attribute_id, AttributeKey::Extent(ref extent_key),
981 ),
982 },
983 value: ObjectValue::Extent(ref extent_value),
984 ..
985 } => Some((*object_id, *attribute_id, extent_key, extent_value)),
986 _ => None,
987 }
988 }
989}
990
991#[cfg(test)]
992mod tests {
993 use super::ObjectKey;
994 use crate::lsm_tree::types::{LayerKey, OrdLowerBound, OrdUpperBound, RangeKey};
995 use std::cmp::Ordering;
996
997 #[test]
998 fn test_next_key() {
999 let next_key = ObjectKey::extent(1, 0, 0..100).next_key().unwrap();
1000 assert_eq!(ObjectKey::extent(1, 0, 101..200).cmp_lower_bound(&next_key), Ordering::Greater);
1001 assert_eq!(ObjectKey::extent(1, 0, 100..200).cmp_lower_bound(&next_key), Ordering::Equal);
1002 assert_eq!(ObjectKey::extent(1, 0, 100..101).cmp_lower_bound(&next_key), Ordering::Equal);
1003 assert_eq!(ObjectKey::extent(1, 0, 99..100).cmp_lower_bound(&next_key), Ordering::Less);
1004 assert_eq!(ObjectKey::extent(1, 0, 0..100).cmp_upper_bound(&next_key), Ordering::Less);
1005 assert_eq!(ObjectKey::extent(1, 0, 99..100).cmp_upper_bound(&next_key), Ordering::Less);
1006 assert_eq!(ObjectKey::extent(1, 0, 100..101).cmp_upper_bound(&next_key), Ordering::Equal);
1007 assert_eq!(ObjectKey::extent(1, 0, 100..200).cmp_upper_bound(&next_key), Ordering::Greater);
1008 assert_eq!(ObjectKey::extent(1, 0, 50..101).cmp_upper_bound(&next_key), Ordering::Equal);
1009 assert_eq!(ObjectKey::extent(1, 0, 50..200).cmp_upper_bound(&next_key), Ordering::Greater);
1010 }
1011 #[test]
1012 fn test_range_key() {
1013 assert_eq!(ObjectKey::object(1).overlaps(&ObjectKey::object(1)), true);
1014 assert_eq!(ObjectKey::object(1).overlaps(&ObjectKey::object(2)), false);
1015 assert_eq!(ObjectKey::extent(1, 0, 0..100).overlaps(&ObjectKey::object(1)), false);
1016 assert_eq!(ObjectKey::object(1).overlaps(&ObjectKey::extent(1, 0, 0..100)), false);
1017 assert_eq!(
1018 ObjectKey::extent(1, 0, 0..100).overlaps(&ObjectKey::extent(2, 0, 0..100)),
1019 false
1020 );
1021 assert_eq!(
1022 ObjectKey::extent(1, 0, 0..100).overlaps(&ObjectKey::extent(1, 1, 0..100)),
1023 false
1024 );
1025 assert_eq!(
1026 ObjectKey::extent(1, 0, 0..100).overlaps(&ObjectKey::extent(1, 0, 0..100)),
1027 true
1028 );
1029
1030 assert_eq!(
1031 ObjectKey::extent(1, 0, 0..50).overlaps(&ObjectKey::extent(1, 0, 49..100)),
1032 true
1033 );
1034 assert_eq!(
1035 ObjectKey::extent(1, 0, 49..100).overlaps(&ObjectKey::extent(1, 0, 0..50)),
1036 true
1037 );
1038
1039 assert_eq!(
1040 ObjectKey::extent(1, 0, 0..50).overlaps(&ObjectKey::extent(1, 0, 50..100)),
1041 false
1042 );
1043 assert_eq!(
1044 ObjectKey::extent(1, 0, 50..100).overlaps(&ObjectKey::extent(1, 0, 0..50)),
1045 false
1046 );
1047 }
1048}