Skip to content

Commit f4c5dfa

Browse files
committed
Precompute DownstairsBlockContext as well
1 parent 2f36619 commit f4c5dfa

File tree

5 files changed

+274
-64
lines changed

5 files changed

+274
-64
lines changed

downstairs/src/deferred.rs

+24
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// Copyright 2023 Oxide Computer Company
2+
use crate::extent::DownstairsBlockContext;
23
use crucible_common::{integrity_hash, CrucibleError};
34
use crucible_protocol::Message;
45

@@ -16,24 +17,47 @@ pub(crate) enum DeferredMessage {
1617
pub(crate) struct PrecomputedWrite {
1718
/// Checks whether incoming hashes are valid
1819
pub validate_hashes_result: Result<(), CrucibleError>,
20+
pub block_contexts: Vec<DownstairsBlockContext>,
1921
}
2022

2123
impl PrecomputedWrite {
2224
#[cfg(test)]
2325
pub(crate) fn empty() -> Self {
2426
PrecomputedWrite {
2527
validate_hashes_result: Ok(()),
28+
block_contexts: vec![],
2629
}
2730
}
2831

2932
/// Precomputes relevant data from a set of writes
3033
pub(crate) fn from_writes(writes: &[crucible_protocol::Write]) -> Self {
3134
let validate_hashes_result = Self::validate_hashes(writes);
35+
let block_contexts = Self::compute_block_contexts(writes);
3236
PrecomputedWrite {
3337
validate_hashes_result,
38+
block_contexts,
3439
}
3540
}
3641

42+
fn compute_block_contexts(
43+
writes: &[crucible_protocol::Write],
44+
) -> Vec<DownstairsBlockContext> {
45+
writes
46+
.iter()
47+
.map(|write| {
48+
// TODO it would be nice if we could profile what % of time we're
49+
// spending on hashes locally vs writing to disk
50+
let on_disk_hash = integrity_hash(&[&write.data[..]]);
51+
52+
DownstairsBlockContext {
53+
block_context: write.block_context,
54+
block: write.offset.value,
55+
on_disk_hash,
56+
}
57+
})
58+
.collect()
59+
}
60+
3761
fn validate_hashes(
3862
writes: &[crucible_protocol::Write],
3963
) -> Result<(), CrucibleError> {

downstairs/src/extent.rs

+28-3
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,29 @@ pub(crate) trait ExtentInner: Send + Sync + Debug {
5252
&mut self,
5353
job_id: JobId,
5454
writes: &[crucible_protocol::Write],
55+
ctxs: &[DownstairsBlockContext],
5556
only_write_unwritten: bool,
5657
iov_max: usize,
5758
) -> Result<(), CrucibleError>;
5859

60+
#[cfg(test)]
61+
fn write_without_precomputed_contexts(
62+
&mut self,
63+
job_id: JobId,
64+
writes: &[crucible_protocol::Write],
65+
only_write_unwritten: bool,
66+
iov_max: usize,
67+
) -> Result<(), CrucibleError> {
68+
let pre = PrecomputedWrite::from_writes(writes);
69+
self.write(
70+
job_id,
71+
writes,
72+
&pre.block_contexts,
73+
only_write_unwritten,
74+
iov_max,
75+
)
76+
}
77+
5978
#[cfg(test)]
6079
fn get_block_contexts(
6180
&mut self,
@@ -75,7 +94,7 @@ pub(crate) trait ExtentInner: Send + Sync + Debug {
7594
}
7695

7796
/// BlockContext, with the addition of block index and on_disk_hash
78-
#[derive(Copy, Clone)]
97+
#[derive(Debug, Copy, Clone, PartialEq)]
7998
pub struct DownstairsBlockContext {
8099
pub block_context: BlockContext,
81100

@@ -536,6 +555,7 @@ impl Extent {
536555
&mut self,
537556
job_id: JobId,
538557
writes: &[crucible_protocol::Write],
558+
ctxs: &[DownstairsBlockContext],
539559
only_write_unwritten: bool,
540560
) -> Result<(), CrucibleError> {
541561
if self.read_only {
@@ -546,8 +566,13 @@ impl Extent {
546566
(job_id.0, self.number, writes.len() as u64)
547567
});
548568

549-
self.inner
550-
.write(job_id, writes, only_write_unwritten, self.iov_max)?;
569+
self.inner.write(
570+
job_id,
571+
writes,
572+
ctxs,
573+
only_write_unwritten,
574+
self.iov_max,
575+
)?;
551576

552577
cdt::extent__write__done!(|| {
553578
(job_id.0, self.number, writes.len() as u64)

0 commit comments

Comments
 (0)