Skip to content

Commit 14c5b60

Browse files
committed
Remove unnecessary mutexes from Downstairs
1 parent 147ae59 commit 14c5b60

File tree

7 files changed

+330
-229
lines changed

7 files changed

+330
-229
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

downstairs/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ opentelemetry.workspace = true
3232
oximeter-producer.workspace = true
3333
oximeter.workspace = true
3434
rand.workspace = true
35+
rayon.workspace = true
3536
repair-client.workspace = true
3637
reqwest.workspace = true
3738
ringbuffer.workspace = true

downstairs/src/dump.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,7 @@ pub async fn dump_region(
5959
* directory index and the value is the ExtentMeta for that region.
6060
*/
6161
for e in &region.extents {
62-
let e = e.lock().await;
63-
let e = match &*e {
62+
let e = match e {
6463
extent::ExtentState::Opened(extent) => extent,
6564
extent::ExtentState::Closed => panic!("dump on closed extent!"),
6665
};
@@ -534,7 +533,7 @@ async fn show_extent(
534533
*/
535534
for (index, dir) in region_dir.iter().enumerate() {
536535
// Open Region read only
537-
let region =
536+
let mut region =
538537
Region::open(dir, Default::default(), false, true, &log)
539538
.await?;
540539

@@ -650,7 +649,7 @@ async fn show_extent_block(
650649
*/
651650
for (index, dir) in region_dir.iter().enumerate() {
652651
// Open Region read only
653-
let region =
652+
let mut region =
654653
Region::open(dir, Default::default(), false, true, &log).await?;
655654

656655
let mut responses = region

downstairs/src/extent.rs

+41-34
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use std::convert::TryInto;
33
use std::fmt;
44
use std::fmt::Debug;
55
use std::fs::{File, OpenOptions};
6-
use tokio::sync::Mutex;
76

87
use anyhow::{anyhow, bail, Context, Result};
98
use nix::unistd::{sysconf, SysconfVar};
@@ -27,10 +26,10 @@ pub struct Extent {
2726
/// data, the metadata about that extent, and the set of dirty blocks that
2827
/// have been written to since last flush. We use dynamic dispatch here to
2928
/// support multiple extent implementations.
30-
inner: Mutex<Box<dyn ExtentInner>>,
29+
inner: Box<dyn ExtentInner + Send + Sync>,
3130
}
3231

33-
pub(crate) trait ExtentInner: Send + Debug {
32+
pub(crate) trait ExtentInner: Send + Sync + Debug {
3433
fn gen_number(&self) -> Result<u64, CrucibleError>;
3534
fn flush_number(&self) -> Result<u64, CrucibleError>;
3635
fn dirty(&self) -> Result<bool, CrucibleError>;
@@ -88,7 +87,7 @@ pub struct DownstairsBlockContext {
8887
/// out of band. If Opened, then this extent is accepting operations.
8988
#[derive(Debug)]
9089
pub enum ExtentState {
91-
Opened(Arc<Extent>),
90+
Opened(Extent),
9291
Closed,
9392
}
9493

@@ -417,7 +416,7 @@ impl Extent {
417416
// using the raw extent format, but for older read-only snapshots that
418417
// were constructed using the SQLite backend, we have to keep them
419418
// as-is.
420-
let inner: Box<dyn ExtentInner> = {
419+
let inner: Box<dyn ExtentInner + Send + Sync> = {
421420
if has_sqlite {
422421
assert!(read_only || force_sqlite_backend);
423422
let inner = extent_inner_sqlite::SqliteInner::open(
@@ -436,25 +435,25 @@ impl Extent {
436435
number,
437436
read_only,
438437
iov_max: Extent::get_iov_max()?,
439-
inner: Mutex::new(inner),
438+
inner,
440439
};
441440

442441
Ok(extent)
443442
}
444443

444+
#[allow(clippy::unused_async)] // this will be async again in the future
445445
pub async fn dirty(&self) -> bool {
446-
self.inner.lock().await.dirty().unwrap()
446+
self.inner.dirty().unwrap()
447447
}
448448

449449
/**
450450
* Close an extent and the metadata db files for it.
451451
*/
452+
#[allow(clippy::unused_async)] // this will be async again in the future
452453
pub async fn close(self) -> Result<(u64, u64, bool), CrucibleError> {
453-
let inner = self.inner.lock().await;
454-
455-
let gen = inner.gen_number().unwrap();
456-
let flush = inner.flush_number().unwrap();
457-
let dirty = inner.dirty().unwrap();
454+
let gen = self.inner.gen_number().unwrap();
455+
let flush = self.inner.flush_number().unwrap();
456+
let dirty = self.inner.dirty().unwrap();
458457

459458
Ok((gen, flush, dirty))
460459
}
@@ -486,7 +485,7 @@ impl Extent {
486485
}
487486
remove_copy_cleanup_dir(dir, number)?;
488487

489-
let inner: Box<dyn ExtentInner> = match backend {
488+
let inner: Box<dyn ExtentInner + Send + Sync> = match backend {
490489
Backend::RawFile => {
491490
Box::new(extent_inner_raw::RawInner::create(dir, def, number)?)
492491
}
@@ -503,7 +502,7 @@ impl Extent {
503502
number,
504503
read_only: false,
505504
iov_max: Extent::get_iov_max()?,
506-
inner: Mutex::new(inner),
505+
inner,
507506
})
508507
}
509508

@@ -516,18 +515,15 @@ impl Extent {
516515
/// `responses` is undefined.
517516
#[instrument]
518517
pub async fn read(
519-
&self,
518+
&mut self,
520519
job_id: JobId,
521520
requests: &[crucible_protocol::ReadRequest],
522521
) -> Result<Vec<crucible_protocol::ReadResponse>, CrucibleError> {
523522
cdt::extent__read__start!(|| {
524523
(job_id.0, self.number, requests.len() as u64)
525524
});
526525

527-
let mut inner = self.inner.lock().await;
528-
529-
let responses = inner.read(job_id, requests, self.iov_max)?;
530-
526+
let responses = self.inner.read(job_id, requests, self.iov_max)?;
531527
cdt::extent__read__done!(|| {
532528
(job_id.0, self.number, requests.len() as u64)
533529
});
@@ -537,7 +533,7 @@ impl Extent {
537533

538534
#[instrument]
539535
pub async fn write(
540-
&self,
536+
&mut self,
541537
job_id: JobId,
542538
writes: &[crucible_protocol::Write],
543539
only_write_unwritten: bool,
@@ -550,8 +546,8 @@ impl Extent {
550546
(job_id.0, self.number, writes.len() as u64)
551547
});
552548

553-
let mut inner = self.inner.lock().await;
554-
inner.write(job_id, writes, only_write_unwritten, self.iov_max)?;
549+
self.inner
550+
.write(job_id, writes, only_write_unwritten, self.iov_max)?;
555551

556552
cdt::extent__write__done!(|| {
557553
(job_id.0, self.number, writes.len() as u64)
@@ -562,16 +558,15 @@ impl Extent {
562558

563559
#[instrument]
564560
pub(crate) async fn flush<I: Into<JobOrReconciliationId> + Debug>(
565-
&self,
561+
&mut self,
566562
new_flush: u64,
567563
new_gen: u64,
568564
id: I, // only used for logging
569565
log: &Logger,
570566
) -> Result<(), CrucibleError> {
571567
let job_id: JobOrReconciliationId = id.into();
572-
let mut inner = self.inner.lock().await;
573568

574-
if !inner.dirty()? {
569+
if !self.inner.dirty()? {
575570
/*
576571
* If we have made no writes to this extent since the last flush,
577572
* we do not need to update the extent on disk
@@ -587,24 +582,36 @@ impl Extent {
587582
crucible_bail!(ModifyingReadOnlyRegion);
588583
}
589584

590-
inner.flush(new_flush, new_gen, job_id)
585+
self.inner.flush(new_flush, new_gen, job_id)
591586
}
592587

588+
#[allow(clippy::unused_async)] // this will be async again in the future
593589
pub async fn get_meta_info(&self) -> ExtentMeta {
594-
let inner = self.inner.lock().await;
595590
ExtentMeta {
596591
ext_version: 0,
597-
gen_number: inner.gen_number().unwrap(),
598-
flush_number: inner.flush_number().unwrap(),
599-
dirty: inner.dirty().unwrap(),
592+
gen_number: self.inner.gen_number().unwrap(),
593+
flush_number: self.inner.flush_number().unwrap(),
594+
dirty: self.inner.dirty().unwrap(),
600595
}
601596
}
602597

603598
#[cfg(test)]
604-
pub(crate) async fn lock(
605-
&self,
606-
) -> tokio::sync::MutexGuard<Box<dyn ExtentInner>> {
607-
self.inner.lock().await
599+
#[allow(clippy::unused_async)] // this will be async again in the future
600+
pub async fn set_dirty_and_block_context(
601+
&mut self,
602+
block_context: &DownstairsBlockContext,
603+
) -> Result<(), CrucibleError> {
604+
self.inner.set_dirty_and_block_context(block_context)
605+
}
606+
607+
#[cfg(test)]
608+
#[allow(clippy::unused_async)] // this will be async again in the future
609+
pub async fn get_block_contexts(
610+
&mut self,
611+
block: u64,
612+
count: u64,
613+
) -> Result<Vec<Vec<DownstairsBlockContext>>, CrucibleError> {
614+
self.inner.get_block_contexts(block, count)
608615
}
609616
}
610617

0 commit comments

Comments
 (0)