diff --git a/src/dbus_api/blockdev/fetch_properties_3_0/methods.rs b/src/dbus_api/blockdev/fetch_properties_3_0/methods.rs index fcec2be93e..ddb6164056 100644 --- a/src/dbus_api/blockdev/fetch_properties_3_0/methods.rs +++ b/src/dbus_api/blockdev/fetch_properties_3_0/methods.rs @@ -15,7 +15,11 @@ use crate::dbus_api::{ blockdev::shared::blockdev_operation, consts, types::TData, util::result_to_tuple, }; -const ALL_PROPERTIES: [&str; 1] = [consts::BLOCKDEV_TOTAL_SIZE_PROP]; +const ALL_PROPERTIES: [&str; 3] = [ + consts::BLOCKDEV_TOTAL_SIZE_PROP, + consts::BLOCKDEV_TOTAL_SIZE_ALLOCATED_PROP, + consts::BLOCKDEV_TOTAL_REAL_SIZE_PROP, +]; fn get_properties_shared( m: &MethodInfo, TData>, @@ -37,6 +41,22 @@ fn get_properties_shared( |_, bd| Ok((*bd.size().bytes()).to_string()), )), )), + consts::BLOCKDEV_TOTAL_SIZE_ALLOCATED_PROP => Some(( + prop, + result_to_tuple(blockdev_operation( + m.tree, + object_path.get_name(), + |_, bd| Ok((*bd.allocated().bytes()).to_string()), + )), + )), + consts::BLOCKDEV_TOTAL_REAL_SIZE_PROP => Some(( + prop, + result_to_tuple(blockdev_operation( + m.tree, + object_path.get_name(), + |_, bd| Ok((*bd.real_size().bytes()).to_string()), + )), + )), _ => None, }) .collect(); diff --git a/src/dbus_api/consts.rs b/src/dbus_api/consts.rs index 8cd331246b..26b0c62d07 100644 --- a/src/dbus_api/consts.rs +++ b/src/dbus_api/consts.rs @@ -46,6 +46,8 @@ pub const BLOCKDEV_TIER_PROP: &str = "Tier"; pub const BLOCKDEV_PHYSICAL_PATH_PROP: &str = "PhysicalPath"; pub const BLOCKDEV_TOTAL_SIZE_PROP: &str = "TotalPhysicalSize"; +pub const BLOCKDEV_TOTAL_SIZE_ALLOCATED_PROP: &str = "TotalPhysicalSizeAllocated"; +pub const BLOCKDEV_TOTAL_REAL_SIZE_PROP: &str = "TotalPhysicalRealSize"; /// Get a list of all the FetchProperties interfaces pub fn fetch_properties_interfaces() -> Vec { diff --git a/src/engine/engine.rs b/src/engine/engine.rs index f318278274..dd4f5287eb 100644 --- a/src/engine/engine.rs +++ b/src/engine/engine.rs @@ -103,6 +103,13 @@ pub trait BlockDev: Debug { /// Get the status of whether a block device is encrypted or not. fn is_encrypted(&self) -> bool; + + /// The total number of sectors allocated from this block device + fn allocated(&self) -> Sectors; + + /// The real size of this block device in sectors. Greater than or equal + /// to the value of size. + fn real_size(&self) -> Sectors; } pub trait Pool: Debug { diff --git a/src/engine/sim_engine/blockdev.rs b/src/engine/sim_engine/blockdev.rs index 067a7e5b18..ad3cd116b4 100644 --- a/src/engine/sim_engine/blockdev.rs +++ b/src/engine/sim_engine/blockdev.rs @@ -59,6 +59,14 @@ impl BlockDev for SimDev { fn is_encrypted(&self) -> bool { self.encryption_info.is_some() } + + fn allocated(&self) -> Sectors { + Bytes::from(IEC::Mi).sectors() + } + + fn real_size(&self) -> Sectors { + 2usize * Bytes::from(IEC::Gi).sectors() + } } impl SimDev { diff --git a/src/engine/strat_engine/backstore/blockdev.rs b/src/engine/strat_engine/backstore/blockdev.rs index 36fc919d38..2bc80ae2f4 100644 --- a/src/engine/strat_engine/backstore/blockdev.rs +++ b/src/engine/strat_engine/backstore/blockdev.rs @@ -71,6 +71,7 @@ pub struct StratBlockDev { user_info: Option, hardware_info: Option, underlying_device: UnderlyingDevice, + real_size: BlockdevSize, } impl StratBlockDev { @@ -95,6 +96,7 @@ impl StratBlockDev { /// /// Precondition: segments in other_segments do not overlap with Stratis /// metadata region. + #[allow(clippy::too_many_arguments)] pub fn new( dev: Device, bda: BDA, @@ -102,6 +104,7 @@ impl StratBlockDev { user_info: Option, hardware_info: Option, underlying_device: UnderlyingDevice, + real_size: BlockdevSize, ) -> StratisResult { let mut segments = vec![(Sectors(0), bda.extended_size().sectors())]; segments.extend(other_segments); @@ -115,6 +118,7 @@ impl StratBlockDev { user_info, hardware_info, underlying_device, + real_size, }) } @@ -340,6 +344,14 @@ impl BlockDev for StratBlockDev { fn is_encrypted(&self) -> bool { self.encryption_info().is_some() } + + fn allocated(&self) -> Sectors { + self.used.used() + } + + fn real_size(&self) -> Sectors { + self.real_size.sectors() + } } impl Recordable for StratBlockDev { diff --git a/src/engine/strat_engine/backstore/devices.rs b/src/engine/strat_engine/backstore/devices.rs index fa387b0bd0..d5a0e38e25 100644 --- a/src/engine/strat_engine/backstore/devices.rs +++ b/src/engine/strat_engine/backstore/devices.rs @@ -473,7 +473,7 @@ pub fn initialize_devices( bda.initialize(&mut f)?; - StratBlockDev::new(devno, bda, &[], None, hw_id, underlying_device) + StratBlockDev::new(devno, bda, &[], None, hw_id, underlying_device, data_size) } /// Clean up an encrypted device after initialization failure. diff --git a/src/engine/strat_engine/liminal/setup.rs b/src/engine/strat_engine/liminal/setup.rs index fc80ce8106..7766e9011b 100644 --- a/src/engine/strat_engine/liminal/setup.rs +++ b/src/engine/strat_engine/liminal/setup.rs @@ -20,7 +20,7 @@ use crate::{ backstore::{CryptHandle, StratBlockDev, UnderlyingDevice}, device::blkdev_size, liminal::device_info::LStratisInfo, - metadata::{StaticHeader, BDA}, + metadata::{BlockdevSize, StaticHeader, BDA}, serde_structs::{BackstoreSave, BaseBlockDevSave, PoolSave}, }, types::{ActionAvailability, BlockDevTier, DevUuid, DevicePath, PoolEncryptionInfo}, @@ -200,8 +200,8 @@ pub fn get_blockdevs( // Return an error if apparent size of Stratis block device appears to // have decreased since metadata was recorded or if size of block // device could not be obtained. - blkdev_size(&OpenOptions::new().read(true).open(&info.ids.devnode)?).and_then( - |actual_size| { + let real_size = blkdev_size(&OpenOptions::new().read(true).open(&info.ids.devnode)?) + .and_then(|actual_size| { let actual_size_sectors = actual_size.sectors(); let recorded_size = bda.dev_size().sectors(); if actual_size_sectors < recorded_size { @@ -213,10 +213,9 @@ pub fn get_blockdevs( ); Err(StratisError::Msg(err_msg)) } else { - Ok(()) + Ok(BlockdevSize::new(actual_size.sectors())) } - }, - )?; + })?; let dev_uuid = bda.dev_uuid(); @@ -261,6 +260,7 @@ pub fn get_blockdevs( Some(handle) => UnderlyingDevice::Encrypted(handle), None => UnderlyingDevice::Unencrypted(DevicePath::new(physical_path)?), }, + real_size, )?, )) }