Skip to content

Commit

Permalink
Fix alignment problems
Browse files Browse the repository at this point in the history
Currently, data allocations from the cap device are data block aligned.
Metadata allocations, however, are not. This can lead to data
allocations after a metadata allocation to become unaligned as well.
This has performance implications. This commit addresses this in a
backwards compatiable way by using our previous metadata size
calculation but rounds the total desired metadata device size up to the
nearest data block size multiple.

This has a few very desirable properties:
1. The metadata allocations will always be aligned to the data block
size boundary.
2. The metadata allocations may appear a bit larger, but the
overall growth of the step function tracks the linear growth of the
original metadata space calculation function.
3. While this commit does not resolve alignment issues for pools that
have already bumped into this problem, this code should theoretically
cause future allocations on affected pools to be in alignment,
minimizing performance impact for future allocations on affected pools.
  • Loading branch information
jbaublitz committed Nov 10, 2023
1 parent ac3af96 commit 361f13f
Showing 1 changed file with 13 additions and 5 deletions.
18 changes: 13 additions & 5 deletions src/engine/strat_engine/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,8 @@ pub fn clevis_luks_regen(dev_path: &Path, keyslot: c_uint) -> StratisResult<()>

/// Determine the number of sectors required to house the specified parameters for
/// the thin pool that determine metadata size.
///
/// Precondition: block_size is a power of 2.
pub fn thin_metadata_size(
block_size: Sectors,
pool_size: Sectors,
Expand Down Expand Up @@ -468,16 +470,22 @@ pub fn thin_metadata_size(
})?
.read_to_string(&mut output)?;
if is_ok {
Ok(min(
THIN_META_MULT_FACTOR
let round = block_size - Sectors(1);
let determined_size = Sectors(
*(THIN_META_MULT_FACTOR
* Sectors(
output
.trim()
.parse::<u64>()
.map_err(|e| StratisError::Msg(e.to_string()))?,
),
MAX_META_SIZE.sectors(),
))
)
+ round)
& !*round,
);
assert!(determined_size % block_size == Sectors(0));
let max = Sectors(*MAX_META_SIZE.sectors() & !*round);
assert!(max % block_size == Sectors(0));
Ok(min(determined_size, max))
} else {
Err(StratisError::Msg(format!(
"thin_metadata_size failed: {output}"
Expand Down

0 comments on commit 361f13f

Please sign in to comment.