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}