btrfs_diskformat/core/
node.rs

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