@@ -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 > ;
@@ -88,7 +87,7 @@ pub struct DownstairsBlockContext {
88
87
/// out of band. If Opened, then this extent is accepting operations.
89
88
#[ derive( Debug ) ]
90
89
pub enum ExtentState {
91
- Opened ( Arc < Extent > ) ,
90
+ Opened ( Extent ) ,
92
91
Closed ,
93
92
}
94
93
@@ -417,7 +416,7 @@ impl Extent {
417
416
// using the raw extent format, but for older read-only snapshots that
418
417
// were constructed using the SQLite backend, we have to keep them
419
418
// as-is.
420
- let inner: Box < dyn ExtentInner > = {
419
+ let inner: Box < dyn ExtentInner + Send + Sync > = {
421
420
if has_sqlite {
422
421
assert ! ( read_only || force_sqlite_backend) ;
423
422
let inner = extent_inner_sqlite:: SqliteInner :: open (
@@ -436,25 +435,25 @@ impl Extent {
436
435
number,
437
436
read_only,
438
437
iov_max : Extent :: get_iov_max ( ) ?,
439
- inner : Mutex :: new ( inner ) ,
438
+ inner,
440
439
} ;
441
440
442
441
Ok ( extent)
443
442
}
444
443
444
+ #[ allow( clippy:: unused_async) ] // this will be async again in the future
445
445
pub async fn dirty ( & self ) -> bool {
446
- self . inner . lock ( ) . await . dirty ( ) . unwrap ( )
446
+ self . inner . dirty ( ) . unwrap ( )
447
447
}
448
448
449
449
/**
450
450
* Close an extent and the metadata db files for it.
451
451
*/
452
+ #[ allow( clippy:: unused_async) ] // this will be async again in the future
452
453
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 ( ) ;
458
457
459
458
Ok ( ( gen, flush, dirty) )
460
459
}
@@ -486,7 +485,7 @@ impl Extent {
486
485
}
487
486
remove_copy_cleanup_dir ( dir, number) ?;
488
487
489
- let inner: Box < dyn ExtentInner > = match backend {
488
+ let inner: Box < dyn ExtentInner + Send + Sync > = match backend {
490
489
Backend :: RawFile => {
491
490
Box :: new ( extent_inner_raw:: RawInner :: create ( dir, def, number) ?)
492
491
}
@@ -503,7 +502,7 @@ impl Extent {
503
502
number,
504
503
read_only : false ,
505
504
iov_max : Extent :: get_iov_max ( ) ?,
506
- inner : Mutex :: new ( inner ) ,
505
+ inner,
507
506
} )
508
507
}
509
508
@@ -516,18 +515,15 @@ impl Extent {
516
515
/// `responses` is undefined.
517
516
#[ instrument]
518
517
pub async fn read (
519
- & self ,
518
+ & mut self ,
520
519
job_id : JobId ,
521
520
requests : & [ crucible_protocol:: ReadRequest ] ,
522
521
) -> Result < Vec < crucible_protocol:: ReadResponse > , CrucibleError > {
523
522
cdt:: extent__read__start!( || {
524
523
( job_id. 0 , self . number, requests. len( ) as u64 )
525
524
} ) ;
526
525
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 ) ?;
531
527
cdt:: extent__read__done!( || {
532
528
( job_id. 0 , self . number, requests. len( ) as u64 )
533
529
} ) ;
@@ -537,7 +533,7 @@ impl Extent {
537
533
538
534
#[ instrument]
539
535
pub async fn write (
540
- & self ,
536
+ & mut self ,
541
537
job_id : JobId ,
542
538
writes : & [ crucible_protocol:: Write ] ,
543
539
only_write_unwritten : bool ,
@@ -550,8 +546,8 @@ impl Extent {
550
546
( job_id. 0 , self . number, writes. len( ) as u64 )
551
547
} ) ;
552
548
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 ) ?;
555
551
556
552
cdt:: extent__write__done!( || {
557
553
( job_id. 0 , self . number, writes. len( ) as u64 )
@@ -562,16 +558,15 @@ impl Extent {
562
558
563
559
#[ instrument]
564
560
pub ( crate ) async fn flush < I : Into < JobOrReconciliationId > + Debug > (
565
- & self ,
561
+ & mut self ,
566
562
new_flush : u64 ,
567
563
new_gen : u64 ,
568
564
id : I , // only used for logging
569
565
log : & Logger ,
570
566
) -> Result < ( ) , CrucibleError > {
571
567
let job_id: JobOrReconciliationId = id. into ( ) ;
572
- let mut inner = self . inner . lock ( ) . await ;
573
568
574
- if !inner. dirty ( ) ? {
569
+ if !self . inner . dirty ( ) ? {
575
570
/*
576
571
* If we have made no writes to this extent since the last flush,
577
572
* we do not need to update the extent on disk
@@ -587,24 +582,36 @@ impl Extent {
587
582
crucible_bail ! ( ModifyingReadOnlyRegion ) ;
588
583
}
589
584
590
- inner. flush ( new_flush, new_gen, job_id)
585
+ self . inner . flush ( new_flush, new_gen, job_id)
591
586
}
592
587
588
+ #[ allow( clippy:: unused_async) ] // this will be async again in the future
593
589
pub async fn get_meta_info ( & self ) -> ExtentMeta {
594
- let inner = self . inner . lock ( ) . await ;
595
590
ExtentMeta {
596
591
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 ( ) ,
600
595
}
601
596
}
602
597
603
598
#[ 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)
608
615
}
609
616
}
610
617
0 commit comments