diff --git a/src/engine/strat_engine/backstore/devices.rs b/src/engine/strat_engine/backstore/devices.rs index c8bdba47e0f..8ca13e31b99 100644 --- a/src/engine/strat_engine/backstore/devices.rs +++ b/src/engine/strat_engine/backstore/devices.rs @@ -32,6 +32,7 @@ use crate::{ BDA, }, names::KeyDescription, + types::StratSigblockVersion, udev::{ block_device_apply, decide_ownership, get_udev_property, UdevOwnership, STRATIS_FS_TYPE, @@ -572,6 +573,7 @@ pub fn initialize_devices( }; let bda = BDA::new( + StratSigblockVersion::V1, StratisIdentifiers::new(pool_uuid, dev_uuid), mda_data_size, data_size, diff --git a/src/engine/strat_engine/metadata/bda.rs b/src/engine/strat_engine/metadata/bda.rs index 731e91bb9fe..1f5c0fb1b52 100644 --- a/src/engine/strat_engine/metadata/bda.rs +++ b/src/engine/strat_engine/metadata/bda.rs @@ -14,6 +14,7 @@ use crate::{ sizes::{BDAExtendedSize, BlockdevSize, MDADataSize, STATIC_HEADER_SIZE}, static_header::{MetadataLocation, StaticHeader, StratisIdentifiers}, }, + types::StratSigblockVersion, writing::SyncAll, }, types::{DevUuid, PoolUuid}, @@ -30,6 +31,7 @@ pub struct BDA { impl Default for BDA { fn default() -> BDA { BDA::new( + StratSigblockVersion::V1, StratisIdentifiers::new(PoolUuid::nil(), DevUuid::nil()), MDADataSize::default(), BlockdevSize::default(), @@ -40,13 +42,19 @@ impl Default for BDA { impl BDA { pub fn new( + sigblock_version: StratSigblockVersion, identifiers: StratisIdentifiers, mda_data_size: MDADataSize, blkdev_size: BlockdevSize, initialization_time: DateTime, ) -> BDA { - let header = - StaticHeader::new(identifiers, mda_data_size, blkdev_size, initialization_time); + let header = StaticHeader::new( + sigblock_version, + identifiers, + mda_data_size, + blkdev_size, + initialization_time, + ); let regions = mda::MDARegions::new(header.mda_size); @@ -172,6 +180,7 @@ mod tests { let mut buf = Cursor::new(vec![0; buf_size]); let bda = BDA::new( + StratSigblockVersion::V1, sh.identifiers, sh.mda_size.region_size().data_size(), sh.blkdev_size, @@ -203,6 +212,7 @@ mod tests { ) ]); let mut bda = BDA::new( + StratSigblockVersion::V1, sh.identifiers, sh.mda_size.region_size().data_size(), sh.blkdev_size, @@ -253,6 +263,7 @@ mod tests { let buf_size = convert_test!(*sh.mda_size.bda_size().sectors().bytes(), u128, usize); let mut buf = Cursor::new(vec![0; buf_size]); let mut bda = BDA::new( + StratSigblockVersion::V1, sh.identifiers, sh.mda_size.region_size().data_size(), sh.blkdev_size, diff --git a/src/engine/strat_engine/metadata/static_header.rs b/src/engine/strat_engine/metadata/static_header.rs index 6ba80aa99eb..ff56ac8815b 100644 --- a/src/engine/strat_engine/metadata/static_header.rs +++ b/src/engine/strat_engine/metadata/static_header.rs @@ -23,6 +23,7 @@ use crate::{ static_header_size, BDAExtendedSize, BlockdevSize, MDADataSize, MDASize, ReservedSize, }, + types::StratSigblockVersion, writing::SyncAll, }, types::{DevUuid, PoolUuid}, @@ -34,8 +35,6 @@ const RESERVED_SECTORS: Sectors = Sectors(3 * IEC::Mi / (SECTOR_SIZE as u64)); / const STRAT_MAGIC: &[u8] = b"!Stra0tis\x86\xff\x02^\x41rh"; -const STRAT_SIGBLOCK_VERSION: u8 = 1; - const CASTAGNOLI: Crc = Crc::::new(&CRC_32_ISCSI); /// Data structure to hold results of reading and parsing a signature buffer. @@ -133,6 +132,7 @@ where #[derive(Debug, Eq, PartialEq)] pub struct StaticHeader { pub blkdev_size: BlockdevSize, + pub sigblock_version: StratSigblockVersion, pub identifiers: StratisIdentifiers, pub mda_size: MDASize, pub reserved_size: ReservedSize, @@ -142,6 +142,7 @@ pub struct StaticHeader { impl StaticHeader { pub fn new( + sigblock_version: StratSigblockVersion, identifiers: StratisIdentifiers, mda_data_size: MDADataSize, blkdev_size: BlockdevSize, @@ -149,6 +150,7 @@ impl StaticHeader { ) -> StaticHeader { StaticHeader { blkdev_size, + sigblock_version, identifiers, mda_size: mda_data_size.region_size().mda_size(), reserved_size: ReservedSize::new(RESERVED_SECTORS), @@ -496,7 +498,7 @@ impl StaticHeader { let mut buf = [0u8; bytes!(static_header_size::SIGBLOCK_SECTORS)]; buf[4..20].clone_from_slice(STRAT_MAGIC); LittleEndian::write_u64(&mut buf[20..28], *self.blkdev_size.sectors()); - buf[28] = STRAT_SIGBLOCK_VERSION; + buf[28] = self.sigblock_version as u8; buf[32..64].clone_from_slice(uuid_to_string!(self.identifiers.pool_uuid).as_bytes()); buf[64..96].clone_from_slice(uuid_to_string!(self.identifiers.device_uuid).as_bytes()); LittleEndian::write_u64(&mut buf[96..104], *self.mda_size.sectors()); @@ -530,12 +532,8 @@ impl StaticHeader { let blkdev_size = BlockdevSize::new(Sectors(LittleEndian::read_u64(&buf[20..28]))); - let version = buf[28]; - if version != STRAT_SIGBLOCK_VERSION { - return Err(StratisError::Msg(format!( - "Unknown sigblock version: {version}" - ))); - } + let version_buf = buf[28]; + let version = StratSigblockVersion::try_from(version_buf)?; let pool_uuid = PoolUuid::parse_str(from_utf8(&buf[32..64])?)?; let dev_uuid = DevUuid::parse_str(from_utf8(&buf[64..96])?)?; @@ -547,6 +545,7 @@ impl StaticHeader { Ok(Some(StaticHeader { identifiers: StratisIdentifiers::new(pool_uuid, dev_uuid), blkdev_size, + sigblock_version: version, mda_size, reserved_size: ReservedSize::new(Sectors(LittleEndian::read_u64(&buf[104..112]))), flags: 0, @@ -623,6 +622,7 @@ pub mod tests { MDADataSize::new(MDADataSize::default().bytes() + Bytes::from(mda_size_factor * 4)); let blkdev_size = (Bytes::from(IEC::Mi) + Sectors(blkdev_size).bytes()).sectors(); StaticHeader::new( + StratSigblockVersion::V1, StratisIdentifiers::new(pool_uuid, dev_uuid), mda_data_size, BlockdevSize::new(blkdev_size), diff --git a/src/engine/strat_engine/types.rs b/src/engine/strat_engine/types.rs index ca9975639f0..d91f68992aa 100644 --- a/src/engine/strat_engine/types.rs +++ b/src/engine/strat_engine/types.rs @@ -11,3 +11,23 @@ use crate::{ pub type BDAResult = Result; pub type BDARecordResult = Result)>; + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum StratSigblockVersion { + V1 = 1, + V2 = 2, +} + +impl TryFrom for StratSigblockVersion { + type Error = StratisError; + + fn try_from(value: u8) -> Result { + match value { + i if i == StratSigblockVersion::V1 as u8 => Ok(StratSigblockVersion::V1), + i if i == StratSigblockVersion::V2 as u8 => Ok(StratSigblockVersion::V2), + _ => Err(StratisError::Msg(format!( + "Unknown sigblock version: {value}" + ))), + } + } +}