devicemapper/
units.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5/// disk sector size in bytes
6pub const SECTOR_SIZE: usize = 512;
7
8/// a kernel defined block size constant for any DM meta device
9/// a DM meta device may store cache device or thinpool device metadata
10/// defined in drivers/md/persistent-data/dm-space-map-metadata.h as
11/// DM_SM_METADATA_BLOCK_SIZE.
12const META_BLOCK_SIZE: Sectors = Sectors(8);
13
14/// The maximum size of a metadata device.
15/// defined in drivers/md/persistent-data/dm-space-map-metadata.h as
16/// DM_SM_METADATA_MAX_BLOCKS.
17/// As far as I can tell, this is not a limit on the size of a designated
18/// metadata device, but instead on the possible usage of that device.
19#[allow(dead_code)]
20const MAX_META_DEV_SIZE: MetaBlocks = MetaBlocks(255 * ((1 << 14) - 64));
21
22range_u64!(
23    /// A type for data blocks
24    DataBlocks,
25    "data blocks"
26);
27
28range_u64!(
29    /// A type for meta blocks
30    MetaBlocks,
31    "meta blocks"
32);
33
34impl MetaBlocks {
35    /// Return the number of Sectors in the MetaBlocks.
36    pub fn sectors(self) -> Sectors {
37        self.0 * META_BLOCK_SIZE
38    }
39}
40
41range_u128!(
42    /// A type for bytes
43    Bytes,
44    "bytes"
45);
46
47impl Bytes {
48    /// Return the number of Sectors fully contained in these bytes.
49    pub fn sectors(self) -> Sectors {
50        Sectors((self.0 / SECTOR_SIZE as u128) as u64)
51    }
52}
53
54range_u64!(
55    /// A type for sectors
56    Sectors,
57    "sectors"
58);
59
60impl Sectors {
61    /// The number of bytes in these sectors.
62    pub fn bytes(self) -> Bytes {
63        // Keep both as u128 before multiplication or overflow could occur
64        Bytes(u128::from(self.0) * SECTOR_SIZE as u128)
65    }
66
67    /// The number of whole metablocks contained in these sectors.
68    pub fn metablocks(self) -> MetaBlocks {
69        MetaBlocks(self / META_BLOCK_SIZE)
70    }
71}
72
73#[cfg(test)]
74mod test {
75    use super::*;
76
77    #[test]
78    fn test_large() {
79        let max_sectors = Sectors(u64::MAX).bytes();
80        let size_sectors = max_sectors.sectors();
81        assert_eq!(size_sectors.bytes(), max_sectors);
82    }
83
84    #[test]
85    fn test_too_large() {
86        let max_bytes = Sectors(u64::MAX).bytes() + Sectors(1).bytes();
87        let sectors = max_bytes.sectors();
88        assert_eq!(sectors, Sectors(0));
89    }
90}