Skip to content

Commit 2e908c2

Browse files
committed
Only create placeholder device when encryption is enabled
1 parent acf4e53 commit 2e908c2

1 file changed

Lines changed: 113 additions & 69 deletions

File tree

  • src/engine/strat_engine/backstore/backstore

src/engine/strat_engine/backstore/backstore/v2.rs

Lines changed: 113 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)