@@ -144,7 +144,7 @@ pub struct Backstore {
144144 data_tier : DataTier < StratBlockDev > ,
145145 /// A linear DM device.
146146 origin : Option < LinearDev > ,
147- /// A placeholder device to be converted to cache or a cache device.
147+ /// A cache device.
148148 cache : Option < CacheDev > ,
149149 /// A placeholder device to be converted to cache; necessary for reencryption support.
150150 placeholder : Option < LinearDev > ,
@@ -153,7 +153,7 @@ pub struct Backstore {
153153 enc : Option < Either < InputEncryptionInfo , CryptHandle > > ,
154154 /// Data allocations on the cap device,
155155 allocs : Vec < ( Sectors , Sectors ) > ,
156- /// Metadata allocations on the cache or placeholder device.
156+ /// Metadata allocations on the cache or origin device.
157157 crypt_meta_allocs : Vec < ( Sectors , Sectors ) > ,
158158}
159159
@@ -163,7 +163,7 @@ impl InternalBackstore for Backstore {
163163 . as_ref ( )
164164 . and_then ( |either| either. as_ref ( ) . right ( ) . map ( |h| h. device ( ) ) )
165165 . or_else ( || self . cache . as_ref ( ) . map ( |c| c. device ( ) ) )
166- . or_else ( || self . placeholder . as_ref ( ) . map ( |lin| lin. device ( ) ) )
166+ . or_else ( || self . origin . as_ref ( ) . map ( |lin| lin. device ( ) ) )
167167 }
168168
169169 fn datatier_allocated_size ( & self ) -> Sectors {
@@ -335,7 +335,7 @@ impl Backstore {
335335 }
336336 } ;
337337
338- let ( placeholder , cache, cache_tier, origin) = if !cachedevs. is_empty ( ) {
338+ let ( cache, cache_tier, origin) = if !cachedevs. is_empty ( ) {
339339 let block_mgr = BlockDevMgr :: new ( cachedevs, Some ( last_update_time) ) ;
340340 match pool_save. backstore . cache_tier {
341341 Some ( ref cache_tier_save) => {
@@ -362,7 +362,7 @@ impl Backstore {
362362 ) ) ;
363363 }
364364 } ;
365- ( None , Some ( cache_device) , Some ( cache_tier) , None )
365+ ( Some ( cache_device) , Some ( cache_tier) , None )
366366 }
367367 None => {
368368 let err_msg = "Cachedevs exist, but cache metadata does not exist" ;
@@ -378,23 +378,33 @@ impl Backstore {
378378 }
379379 }
380380 } else {
381- let placeholder = match make_placeholder_dev ( pool_uuid, & origin) {
382- Ok ( pl) => pl,
383- Err ( e) => return Err ( ( e, data_tier. block_mgr . into_bdas ( ) ) ) ,
384- } ;
385- ( Some ( placeholder) , None , None , Some ( origin) )
381+ ( None , None , Some ( origin) )
386382 } ;
387383
388384 let metadata_enc_enabled = pool_save. features . contains ( & PoolFeatures :: Encryption ) ;
389- let crypt_physical_path = & once ( DEVICEMAPPER_PATH )
390- . chain ( once (
391- format_backstore_ids ( pool_uuid, CacheRole :: Cache )
392- . 0
393- . to_string ( )
394- . as_str ( ) ,
395- ) )
396- . collect :: < PathBuf > ( ) ;
397- let has_header = match CryptHandle :: load_metadata ( crypt_physical_path, pool_uuid) {
385+ let crypt_physical_path = match cache
386+ . as_ref ( )
387+ . map ( |c| c. devnode ( ) )
388+ . or_else ( || origin. as_ref ( ) . map ( |o| o. devnode ( ) ) )
389+ {
390+ Some ( p) => p,
391+ None => {
392+ return Err ( (
393+ StratisError :: Msg ( "No allocations to backstore detected" . to_string ( ) ) ,
394+ data_tier
395+ . block_mgr
396+ . into_bdas ( )
397+ . into_iter ( )
398+ . chain (
399+ cache_tier
400+ . map ( |ct| ct. block_mgr . into_bdas ( ) )
401+ . unwrap_or_default ( ) ,
402+ )
403+ . collect :: < HashMap < _ , _ > > ( ) ,
404+ ) ) ;
405+ }
406+ } ;
407+ let has_header = match CryptHandle :: load_metadata ( & crypt_physical_path, pool_uuid) {
398408 Ok ( opt) => opt. is_some ( ) ,
399409 Err ( e) => {
400410 return Err ( (
@@ -412,12 +422,49 @@ impl Backstore {
412422 ) ) ;
413423 }
414424 } ;
415- let enc = match ( metadata_enc_enabled, has_header, passphrase. as_ref ( ) ) {
425+ let ( placeholder , enc) = match ( metadata_enc_enabled, has_header, passphrase. as_ref ( ) ) {
416426 ( true , true , pass) => {
417- match CryptHandle :: setup ( crypt_physical_path, pool_uuid, token_slot, pass) {
427+ let placeholder = match ( metadata_enc_enabled, cache. as_ref ( ) ) {
428+ ( false , _) => None ,
429+ ( _, Some ( _) ) => None ,
430+ ( _, None ) => match make_placeholder_dev (
431+ pool_uuid,
432+ origin. as_ref ( ) . expect ( "Must succeed, is_some()" ) ,
433+ ) {
434+ Ok ( pl) => Some ( pl) ,
435+ Err ( e) => return Err ( ( e, data_tier. block_mgr . into_bdas ( ) ) ) ,
436+ } ,
437+ } ;
438+ match CryptHandle :: setup (
439+ match placeholder
440+ . as_ref ( )
441+ . map ( |p| p. devnode ( ) )
442+ . or_else ( || cache. as_ref ( ) . map ( |c| c. devnode ( ) ) )
443+ {
444+ Some ( ref p) => p,
445+ None => {
446+ return Err ( (
447+ StratisError :: Msg ( "" . to_string ( ) ) ,
448+ data_tier
449+ . block_mgr
450+ . into_bdas ( )
451+ . into_iter ( )
452+ . chain (
453+ cache_tier
454+ . map ( |ct| ct. block_mgr . into_bdas ( ) )
455+ . unwrap_or_default ( ) ,
456+ )
457+ . collect :: < HashMap < _ , _ > > ( ) ,
458+ ) )
459+ }
460+ } ,
461+ pool_uuid,
462+ token_slot,
463+ pass,
464+ ) {
418465 Ok ( opt) => {
419466 if let Some ( h) = opt {
420- Some ( Either :: Right ( h) )
467+ ( placeholder , Some ( Either :: Right ( h) ) )
421468 } else {
422469 return Err (
423470 (
@@ -491,7 +538,7 @@ impl Backstore {
491538 . collect :: < HashMap < _ , _ > > ( ) ,
492539 ) ) ;
493540 }
494- ( false , _, _) => None ,
541+ ( false , _, _) => ( None , None ) ,
495542 } ;
496543
497544 Ok ( Backstore {
@@ -586,8 +633,6 @@ impl Backstore {
586633 ///
587634 /// Precondition: Must be invoked only after some space has been allocated
588635 /// from the backstore. This ensures that there is certainly a cap device.
589- // Precondition: self.cache.is_none() && self.placeholder.is_some()
590- // Postcondition: self.cache.is_some() && self.placeholder.is_none()
591636 pub fn init_cache (
592637 & mut self ,
593638 pool_uuid : PoolUuid ,
@@ -612,11 +657,9 @@ impl Backstore {
612657 let origin = self . origin
613658 . take ( )
614659 . expect ( "some space has already been allocated from the backstore => (cache_tier.is_none() <=> self.origin.is_some())" ) ;
615- let placeholder = self . placeholder
616- . take ( )
617- . expect ( "some space has already been allocated from the backstore => (cache_tier.is_none() <=> self.placeholder.is_some())" ) ;
660+ let placeholder = self . placeholder . take ( ) ;
618661
619- let cache = make_cache ( pool_uuid, & cache_tier, origin, Some ( placeholder) , true ) ?;
662+ let cache = make_cache ( pool_uuid, & cache_tier, origin, placeholder, true ) ?;
620663
621664 self . cache = Some ( cache) ;
622665
@@ -696,27 +739,26 @@ impl Backstore {
696739 fn extend_cap_device ( & mut self , pool_uuid : PoolUuid ) -> StratisResult < ( ) > {
697740 let create = match (
698741 self . cache . as_mut ( ) ,
699- self . placeholder
700- . as_mut ( )
701- . and_then ( |p| self . origin . as_mut ( ) . map ( |o| ( p, o) ) ) ,
742+ self . placeholder . as_mut ( ) ,
743+ self . origin . as_mut ( ) ,
702744 self . enc . as_mut ( ) ,
703745 ) {
704- ( None , None , None ) => true ,
705- ( _, _, Some ( Either :: Left ( _) ) ) => true ,
706- ( Some ( cache) , None , Some ( Either :: Right ( handle) ) ) => {
746+ ( None , None , None , None ) => true ,
747+ ( _, _, _ , Some ( Either :: Left ( _) ) ) => true ,
748+ ( Some ( cache) , None , None , Some ( Either :: Right ( handle) ) ) => {
707749 let table = self . data_tier . segments . map_to_dm ( ) ;
708750 cache. set_origin_table ( get_dm ( ) , table) ?;
709751 cache. resume ( get_dm ( ) ) ?;
710752 handle. resize ( None ) ?;
711753 false
712754 }
713- ( Some ( cache) , None , None ) => {
755+ ( Some ( cache) , None , None , None ) => {
714756 let table = self . data_tier . segments . map_to_dm ( ) ;
715757 cache. set_origin_table ( get_dm ( ) , table) ?;
716758 cache. resume ( get_dm ( ) ) ?;
717759 false
718760 }
719- ( None , Some ( ( placeholder, origin) ) , Some ( Either :: Right ( handle) ) ) => {
761+ ( None , Some ( placeholder) , Some ( origin) , Some ( Either :: Right ( handle) ) ) => {
720762 let table = self . data_tier . segments . map_to_dm ( ) ;
721763 origin. set_table ( get_dm ( ) , table) ?;
722764 origin. resume ( get_dm ( ) ) ?;
@@ -733,56 +775,58 @@ impl Backstore {
733775 handle. resize ( None ) ?;
734776 false
735777 }
736- ( None , Some ( ( cap , linear) ) , None ) => {
778+ ( None , None , Some ( linear) , None ) => {
737779 let table = self . data_tier . segments . map_to_dm ( ) ;
738780 linear. set_table ( get_dm ( ) , table) ?;
739781 linear. resume ( get_dm ( ) ) ?;
740- let table = vec ! [ TargetLine :: new(
741- Sectors ( 0 ) ,
742- linear. size( ) ,
743- LinearDevTargetParams :: Linear ( LinearTargetParams :: new(
744- linear. device( ) ,
745- Sectors ( 0 ) ,
746- ) ) ,
747- ) ] ;
748- cap. set_table ( get_dm ( ) , table) ?;
749- cap. resume ( get_dm ( ) ) ?;
750782 false
751783 }
752- _ => panic ! ( "NOT (self.cache().is_some() AND self.origin .is_some())" ) ,
784+ _ => panic ! ( "NOT (self.cache().is_some() AND self.placeholder .is_some())" ) ,
753785 } ;
754786
755787 if create {
756788 let table = self . data_tier . segments . map_to_dm ( ) ;
757789 let ( dm_name, dm_uuid) = format_backstore_ids ( pool_uuid, CacheRole :: OriginSub ) ;
758790 let origin = LinearDev :: setup ( get_dm ( ) , & dm_name, Some ( & dm_uuid) , table) ?;
759- let placeholder = make_placeholder_dev ( pool_uuid, & origin) ?;
760- let handle = match self . enc {
761- Some ( Either :: Left ( ref einfo) ) => Some ( CryptHandle :: initialize (
762- & once ( DEVICEMAPPER_PATH )
763- . chain ( once (
764- format_backstore_ids ( pool_uuid, CacheRole :: Cache )
765- . 0
766- . to_string ( )
767- . as_str ( ) ,
768- ) )
769- . collect :: < PathBuf > ( ) ,
770- pool_uuid,
771- einfo,
772- None ,
773- ) ?) ,
791+ let ( placeholder, handle) = match self . enc {
792+ Some ( Either :: Left ( ref einfo) ) => {
793+ let placeholder = if self . cache . is_some ( ) {
794+ None
795+ } else {
796+ Some ( make_placeholder_dev ( pool_uuid, & origin) ?)
797+ } ;
798+ (
799+ placeholder,
800+ Some ( CryptHandle :: initialize (
801+ & once ( DEVICEMAPPER_PATH )
802+ . chain ( once (
803+ format_backstore_ids ( pool_uuid, CacheRole :: Cache )
804+ . 0
805+ . to_string ( )
806+ . as_str ( ) ,
807+ ) )
808+ . collect :: < PathBuf > ( ) ,
809+ pool_uuid,
810+ einfo,
811+ None ,
812+ ) ?) ,
813+ )
814+ }
774815 Some ( Either :: Right ( _) ) => unreachable ! ( "Checked above" ) ,
775816 None => {
776817 manual_wipe (
777- & placeholder. devnode ( ) ,
818+ & match self . cache . as_ref ( ) {
819+ Some ( c) => c. devnode ( ) ,
820+ None => origin. devnode ( ) ,
821+ } ,
778822 Sectors ( 0 ) ,
779823 DEFAULT_CRYPT_DATA_OFFSET_V2 ,
780824 ) ?;
781- None
825+ ( None , None )
782826 }
783827 } ;
784828 self . origin = Some ( origin) ;
785- self . placeholder = Some ( placeholder) ;
829+ self . placeholder = placeholder;
786830 self . enc = handle. map ( Either :: Right ) ;
787831 }
788832
@@ -855,8 +899,8 @@ impl Backstore {
855899 self . enc
856900 . as_ref ( )
857901 . and_then ( |either| either. as_ref ( ) . right ( ) . map ( |handle| handle. size ( ) ) )
858- . or_else ( || self . placeholder . as_ref ( ) . map ( |d| d. size ( ) ) )
859902 . or_else ( || self . cache . as_ref ( ) . map ( |d| d. size ( ) ) )
903+ . or_else ( || self . origin . as_ref ( ) . map ( |d| d. size ( ) ) )
860904 . unwrap_or ( Sectors ( 0 ) )
861905 }
862906
@@ -1614,7 +1658,7 @@ mod tests {
16141658
16151659 invariant ( & backstore) ;
16161660
1617- assert_eq ! ( backstore. device( ) , old_device) ;
1661+ assert_neq ! ( backstore. device( ) , old_device) ;
16181662
16191663 backstore. destroy ( pool_uuid) . unwrap ( ) ;
16201664 }
0 commit comments