1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
use {
crate::{
constants::{
CSUM_SIZE, FSID_SIZE, LABEL_SIZE, MAX_SYSTEM_CHUNK_ARRAY_SIZE, NUM_BACKUP_ROOTS,
},
DevItem, RootBackup,
},
byteorder::LE,
num_enum::{IntoPrimitive, TryFromPrimitive},
static_assertions::const_assert_eq,
strum::EnumIter,
zerocopy::{AsBytes, FromBytes, Unaligned, U16, U32, U64},
};
/// The layout of the superblock. A valid superblock must exist for most btrfs implementations to
/// mount the filesystem.
///
/// The primary superblock is located at [`PRIMARY_SUPERBLOCK_ADDR`].
///
/// There are additional copies of the superblock located at [`SUPERBLOCK_ADDRS`], if those addresses
/// are valid, respectively.
///
///
/// [`PRIMARY_SUPERBLOCK_ADDR`]: crate::constants::PRIMARY_SUPERBLOCK_ADDR
/// [`SUPERBLOCK_ADDRS`]: crate::constants::SUPERBLOCK_ADDRS
///
/// # Resources
///
/// * <https://btrfs.wiki.kernel.org/index.php/Data_Structures#btrfs_super_block>
/// * <https://btrfs.wiki.kernel.org/index.php/On-disk_Format#Superblock>
#[derive(Copy, Clone, AsBytes, FromBytes, Unaligned)]
#[repr(C, packed)]
pub struct SuperBlock {
/// Checksum of everything past this field.
pub csum: [u8; CSUM_SIZE],
/// Filesystem UUID.
pub fsid: [u8; FSID_SIZE],
/// The physical address of this block.
pub bytenr: U64<LE>,
/// Flags
pub flags: U64<LE>,
/// The magic must be equal to `"_BHRfS_M"` in ASCII.
pub magic: U64<LE>,
/// The generation of the superblock. In SSD mode, not all superblocks may be updated, so the
/// latest generation superblock should be used.
pub generation: U64<LE>,
/// The logical address of the root tree's root.
pub root: U64<LE>,
/// The logical address of the chunk tree's root.
pub chunk_root: U64<LE>,
/// The logical address of the log tree's root.
pub log_root: U64<LE>,
/// FIXME: find out what this is!
pub log_root_transid: U64<LE>,
/// FIXME: document this!
pub total_bytes: U64<LE>,
pub bytes_used: U64<LE>,
/// The root directory's object ID, which is typically 6.
pub root_dir_objectid: U64<LE>,
/// The number of devices the current filesystem spans.
pub num_devices: U64<LE>,
/// The size of a sector.
pub sectorsize: U32<LE>,
pub nodesize: U32<LE>,
/// This is currently unused.
pub leafsize: U32<LE>,
pub stripesize: U32<LE>,
/// The size of [`sys_chunk_array`] found in the superblock.
///
/// [`sys_chunk_array`]: SuperBlock::sys_chunk_array
pub sys_chunk_array_size: U32<LE>,
pub chunk_root_generation: U64<LE>,
pub compat_flags: U64<LE>,
/// Only implementations that support these flags can write to the filesystem.
pub compat_ro_flags: U64<LE>,
/// Only implementations that support these flags can use the filesystem.
pub incompat_flags: U64<LE>,
/// The checksum type.
///
/// This should correspond with a value from [`ChecksumType`].
///
/// [`ChecksumType`]: crate::ChecksumType
pub csum_type: U16<LE>,
pub root_level: u8,
pub chunk_root_level: u8,
pub log_root_level: u8,
pub dev_item: DevItem,
/// The label represented as a null-terminated UTF-8 string. May not contain `'/'` or `'\\'`.
pub label: [u8; LABEL_SIZE],
pub cache_generation: U64<LE>,
pub uuid_tree_generation: U64<LE>,
/// Reserved for extensibility.
pub _reserved: [U64<LE>; 30],
pub sys_chunk_array: [u8; MAX_SYSTEM_CHUNK_ARRAY_SIZE],
pub super_roots: [RootBackup; NUM_BACKUP_ROOTS],
pub _unused1: [u8; 565],
}
const_assert_eq!(core::mem::size_of::<SuperBlock>(), 4096);
#[derive(Copy, Clone, Debug, Hash, PartialEq, EnumIter, IntoPrimitive, TryFromPrimitive)]
#[repr(u16)]
pub enum ChecksumType {
CRC32C = 0,
XXHASH64 = 1,
SHA256 = 2,
BLAKE2b = 3,
}