Skip to content

Commit 0c68777

Browse files
committed
Remove unnecessary mutexes from Downstairs
1 parent 13f38b9 commit 0c68777

File tree

7 files changed

+334
-228
lines changed

7 files changed

+334
-228
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-33
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>;
@@ -89,7 +88,7 @@ pub struct DownstairsBlockContext {
8988
/// out of band. If Opened, then this extent is accepting operations.
9089
#[derive(Debug)]
9190
pub enum ExtentState {
92-
Opened(Arc<Extent>),
91+
Opened(Extent),
9392
Closed,
9493
}
9594

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

443442
Ok(extent)
444443
}
445444

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

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

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

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

@@ -517,7 +516,7 @@ impl Extent {
517516
/// `responses` is undefined.
518517
#[instrument]
519518
pub async fn read(
520-
&self,
519+
&mut self,
521520
job_id: JobId,
522521
requests: &[&crucible_protocol::ReadRequest],
523522
responses: &mut Vec<crucible_protocol::ReadResponse>,
@@ -526,9 +525,7 @@ impl Extent {
526525
(job_id.0, self.number, requests.len() as u64)
527526
});
528527

529-
let mut inner = self.inner.lock().await;
530-
531-
inner.read(job_id, requests, responses, self.iov_max)?;
528+
self.inner.read(job_id, requests, responses, self.iov_max)?;
532529

533530
cdt::extent__read__done!(|| {
534531
(job_id.0, self.number, requests.len() as u64)
@@ -539,7 +536,7 @@ impl Extent {
539536

540537
#[instrument]
541538
pub async fn write(
542-
&self,
539+
&mut self,
543540
job_id: JobId,
544541
writes: &[&crucible_protocol::Write],
545542
only_write_unwritten: bool,
@@ -552,8 +549,8 @@ impl Extent {
552549
(job_id.0, self.number, writes.len() as u64)
553550
});
554551

555-
let mut inner = self.inner.lock().await;
556-
inner.write(job_id, writes, only_write_unwritten, self.iov_max)?;
552+
self.inner
553+
.write(job_id, writes, only_write_unwritten, self.iov_max)?;
557554

558555
cdt::extent__write__done!(|| {
559556
(job_id.0, self.number, writes.len() as u64)
@@ -564,16 +561,15 @@ impl Extent {
564561

565562
#[instrument]
566563
pub(crate) async fn flush<I: Into<JobOrReconciliationId> + Debug>(
567-
&self,
564+
&mut self,
568565
new_flush: u64,
569566
new_gen: u64,
570567
id: I, // only used for logging
571568
log: &Logger,
572569
) -> Result<(), CrucibleError> {
573570
let job_id: JobOrReconciliationId = id.into();
574-
let mut inner = self.inner.lock().await;
575571

576-
if !inner.dirty()? {
572+
if !self.inner.dirty()? {
577573
/*
578574
* If we have made no writes to this extent since the last flush,
579575
* we do not need to update the extent on disk
@@ -589,24 +585,36 @@ impl Extent {
589585
crucible_bail!(ModifyingReadOnlyRegion);
590586
}
591587

592-
inner.flush(new_flush, new_gen, job_id)
588+
self.inner.flush(new_flush, new_gen, job_id)
593589
}
594590

591+
#[allow(clippy::unused_async)] // this will be async again in the future
595592
pub async fn get_meta_info(&self) -> ExtentMeta {
596-
let inner = self.inner.lock().await;
597593
ExtentMeta {
598594
ext_version: 0,
599-
gen_number: inner.gen_number().unwrap(),
600-
flush_number: inner.flush_number().unwrap(),
601-
dirty: inner.dirty().unwrap(),
595+
gen_number: self.inner.gen_number().unwrap(),
596+
flush_number: self.inner.flush_number().unwrap(),
597+
dirty: self.inner.dirty().unwrap(),
602598
}
603599
}
604600

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

0 commit comments

Comments
 (0)