btrfs_diskformat/core/
node.rs

1use crate::{Key, UuidBytes, constants::CSUM_SIZE};
2use num_enum::{IntoPrimitive, TryFromPrimitive};
3use static_assertions::const_assert_eq;
4use strum::EnumIter;
5use zerocopy::little_endian::{U32 as U32LE, U64 as U64LE};
6use zerocopy_derive::*;
7
8/// The data stored at the start of every node.
9#[derive(Clone, Debug, IntoBytes, TryFromBytes, Unaligned, KnownLayout)]
10#[repr(C, packed)]
11pub struct Header {
12    /// The checksum of everything after this field, including the
13    /// internal/leaf node specific part.
14    pub csum: [u8; CSUM_SIZE],
15
16    /// The filesystem UUID.
17    pub fs_uuid: UuidBytes,
18
19    /// The logical address of this node.
20    pub logical_address: U64LE,
21
22    /// The first 7 bits represent flags.
23    pub flags: [u8; 7],
24
25    /// The backref revision, which maps to a [`BackrefRevision`] value.
26    pub backref_rev: BackrefRevision,
27
28    /// The chunk tree UUID.
29    pub chunk_tree_uuid: UuidBytes,
30
31    /// The generation of this node.
32    pub generation: U64LE,
33
34    /// The ID of the tree containing this node.
35    pub tree_id: U64LE,
36
37    /// The number of items held in this node.
38    pub num_items: U32LE,
39
40    /// The level of this node. 0 indicates it is a leaf node.
41    pub level: u8,
42}
43const_assert_eq!(core::mem::size_of::<Header>(), 101);
44
45/// For internal (non-leaf) nodes, the [node header] is followed by a dynamic amount of key
46/// pointers.
47///
48/// [node header]: Header
49#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Unaligned, KnownLayout)]
50#[repr(C, packed)]
51pub struct KeyPointer {
52    pub key: Key,
53    pub block_pointer: U64LE,
54    pub generation: U64LE,
55}
56const_assert_eq!(core::mem::size_of::<KeyPointer>(), 33);
57
58/// For leaf nodes, the [node header] is followed by a dynamic number of items.
59///
60/// The item data is stored at the end of the node, as pointed to by the [offset] and [size].
61/// The contents of the item are specified in the [key].
62///
63/// [node header]: Header
64/// [offset]: Item::offset
65/// [size]: Item::size
66/// [key]: Item::key
67#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Unaligned, KnownLayout)]
68#[repr(C, packed)]
69pub struct Item {
70    /// The key that contains the ID and contents of this [Item].
71    pub key: Key,
72
73    /// Offset relative to the end of the header.
74    pub offset: U32LE,
75
76    /// The size of the data.
77    pub size: U32LE,
78}
79const_assert_eq!(core::mem::size_of::<Item>(), 25);
80
81#[derive(
82    Copy,
83    Clone,
84    Debug,
85    Hash,
86    PartialEq,
87    EnumIter,
88    IntoPrimitive,
89    TryFromPrimitive,
90    IntoBytes,
91    TryFromBytes,
92    Unaligned,
93    KnownLayout,
94)]
95#[repr(u8)]
96pub enum BackrefRevision {
97    /// Indicates asn old filesystem.
98    Old = 0,
99
100    /// Indicates a new filesystem.
101    Mixed = 1,
102}
103const_assert_eq!(core::mem::size_of::<BackrefRevision>(), 1);