@@ -3,7 +3,6 @@ use std::convert::TryInto;
3
3
use std:: fmt;
4
4
use std:: fmt:: Debug ;
5
5
use std:: fs:: { File , OpenOptions } ;
6
- use tokio:: sync:: Mutex ;
7
6
8
7
use anyhow:: { anyhow, bail, Context , Result } ;
9
8
use nix:: unistd:: { sysconf, SysconfVar } ;
@@ -27,10 +26,10 @@ pub struct Extent {
27
26
/// data, the metadata about that extent, and the set of dirty blocks that
28
27
/// have been written to since last flush. We use dynamic dispatch here to
29
28
/// support multiple extent implementations.
30
- inner : Mutex < Box < dyn ExtentInner > > ,
29
+ inner : Box < dyn ExtentInner + Send + Sync > ,
31
30
}
32
31
33
- pub ( crate ) trait ExtentInner : Send + Debug {
32
+ pub ( crate ) trait ExtentInner : Send + Sync + Debug {
34
33
fn gen_number ( & self ) -> Result < u64 , CrucibleError > ;
35
34
fn flush_number ( & self ) -> Result < u64 , CrucibleError > ;
36
35
fn dirty ( & self ) -> Result < bool , CrucibleError > ;
@@ -89,7 +88,7 @@ pub struct DownstairsBlockContext {
89
88
/// out of band. If Opened, then this extent is accepting operations.
90
89
#[ derive( Debug ) ]
91
90
pub enum ExtentState {
92
- Opened ( Arc < Extent > ) ,
91
+ Opened ( Extent ) ,
93
92
Closed ,
94
93
}
95
94
@@ -418,7 +417,7 @@ impl Extent {
418
417
// using the raw extent format, but for older read-only snapshots that
419
418
// were constructed using the SQLite backend, we have to keep them
420
419
// as-is.
421
- let inner: Box < dyn ExtentInner > = {
420
+ let inner: Box < dyn ExtentInner + Send + Sync > = {
422
421
if has_sqlite {
423
422
assert ! ( read_only || force_sqlite_backend) ;
424
423
let inner = extent_inner_sqlite:: SqliteInner :: open (
@@ -437,25 +436,25 @@ impl Extent {
437
436
number,
438
437
read_only,
439
438
iov_max : Extent :: get_iov_max ( ) ?,
440
- inner : Mutex :: new ( inner ) ,
439
+ inner,
441
440
} ;
442
441
443
442
Ok ( extent)
444
443
}
445
444
445
+ #[ allow( clippy:: unused_async) ] // this will be async again in the future
446
446
pub async fn dirty ( & self ) -> bool {
447
- self . inner . lock ( ) . await . dirty ( ) . unwrap ( )
447
+ self . inner . dirty ( ) . unwrap ( )
448
448
}
449
449
450
450
/**
451
451
* Close an extent and the metadata db files for it.
452
452
*/
453
+ #[ allow( clippy:: unused_async) ] // this will be async again in the future
453
454
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 ( ) ;
459
458
460
459
Ok ( ( gen, flush, dirty) )
461
460
}
@@ -487,7 +486,7 @@ impl Extent {
487
486
}
488
487
remove_copy_cleanup_dir ( dir, number) ?;
489
488
490
- let inner: Box < dyn ExtentInner > = match backend {
489
+ let inner: Box < dyn ExtentInner + Send + Sync > = match backend {
491
490
Backend :: RawFile => {
492
491
Box :: new ( extent_inner_raw:: RawInner :: create ( dir, def, number) ?)
493
492
}
@@ -504,7 +503,7 @@ impl Extent {
504
503
number,
505
504
read_only : false ,
506
505
iov_max : Extent :: get_iov_max ( ) ?,
507
- inner : Mutex :: new ( inner ) ,
506
+ inner,
508
507
} )
509
508
}
510
509
@@ -517,7 +516,7 @@ impl Extent {
517
516
/// `responses` is undefined.
518
517
#[ instrument]
519
518
pub async fn read (
520
- & self ,
519
+ & mut self ,
521
520
job_id : JobId ,
522
521
requests : & [ & crucible_protocol:: ReadRequest ] ,
523
522
responses : & mut Vec < crucible_protocol:: ReadResponse > ,
@@ -526,9 +525,7 @@ impl Extent {
526
525
( job_id. 0 , self . number, requests. len( ) as u64 )
527
526
} ) ;
528
527
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 ) ?;
532
529
533
530
cdt:: extent__read__done!( || {
534
531
( job_id. 0 , self . number, requests. len( ) as u64 )
@@ -539,7 +536,7 @@ impl Extent {
539
536
540
537
#[ instrument]
541
538
pub async fn write (
542
- & self ,
539
+ & mut self ,
543
540
job_id : JobId ,
544
541
writes : & [ & crucible_protocol:: Write ] ,
545
542
only_write_unwritten : bool ,
@@ -552,8 +549,8 @@ impl Extent {
552
549
( job_id. 0 , self . number, writes. len( ) as u64 )
553
550
} ) ;
554
551
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 ) ?;
557
554
558
555
cdt:: extent__write__done!( || {
559
556
( job_id. 0 , self . number, writes. len( ) as u64 )
@@ -564,16 +561,15 @@ impl Extent {
564
561
565
562
#[ instrument]
566
563
pub ( crate ) async fn flush < I : Into < JobOrReconciliationId > + Debug > (
567
- & self ,
564
+ & mut self ,
568
565
new_flush : u64 ,
569
566
new_gen : u64 ,
570
567
id : I , // only used for logging
571
568
log : & Logger ,
572
569
) -> Result < ( ) , CrucibleError > {
573
570
let job_id: JobOrReconciliationId = id. into ( ) ;
574
- let mut inner = self . inner . lock ( ) . await ;
575
571
576
- if !inner. dirty ( ) ? {
572
+ if !self . inner . dirty ( ) ? {
577
573
/*
578
574
* If we have made no writes to this extent since the last flush,
579
575
* we do not need to update the extent on disk
@@ -589,24 +585,36 @@ impl Extent {
589
585
crucible_bail ! ( ModifyingReadOnlyRegion ) ;
590
586
}
591
587
592
- inner. flush ( new_flush, new_gen, job_id)
588
+ self . inner . flush ( new_flush, new_gen, job_id)
593
589
}
594
590
591
+ #[ allow( clippy:: unused_async) ] // this will be async again in the future
595
592
pub async fn get_meta_info ( & self ) -> ExtentMeta {
596
- let inner = self . inner . lock ( ) . await ;
597
593
ExtentMeta {
598
594
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 ( ) ,
602
598
}
603
599
}
604
600
605
601
#[ 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)
610
618
}
611
619
}
612
620
0 commit comments