From 03f9f8b4836102232cd5afe0e7fdd31cef0b842a Mon Sep 17 00:00:00 2001 From: "Bryn M. Reeves" Date: Thu, 6 Apr 2023 14:50:56 +0100 Subject: [PATCH 1/3] Add 'create_options' to device new() and setup() methods Add the ability for callers to specify the DmOptions value to use when creating or setting up lineardev, thindev, thinpooldev, and cachedev. The DmOptions value is wrapped in an Option which if set to None gives the previous devicemapper-rs default behaviour. This allows clients of the crate to opt in to controlling device visibility and other DmOptions/DmUdevFlags behaviour when creating or setting up devices. --- src/cachedev.rs | 21 ++++++++--- src/lineardev.rs | 30 +++++++++------- src/thindev.rs | 88 +++++++++++++++++++++++++++++++++------------- src/thinpooldev.rs | 22 +++++++++--- 4 files changed, 116 insertions(+), 45 deletions(-) diff --git a/src/cachedev.rs b/src/cachedev.rs index 028b7f51..1e5388e3 100644 --- a/src/cachedev.rs +++ b/src/cachedev.rs @@ -566,14 +566,19 @@ impl CacheDev { cache: LinearDev, origin: LinearDev, cache_block_size: Sectors, + create_options: Option, ) -> DmResult { if device_exists(dm, name)? { let err_msg = format!("cachedev {name} already exists"); return Err(DmError::Dm(ErrorEnum::Invalid, err_msg)); } + let options = match create_options { + Some(options) => options, + None => DmOptions::private(), + }; let table = CacheDev::gen_default_table(&meta, &cache, &origin, cache_block_size); - let dev_info = device_create(dm, name, uuid, &table, DmOptions::private())?; + let dev_info = device_create(dm, name, uuid, &table, options)?; Ok(CacheDev { dev_info: Box::new(dev_info), @@ -593,6 +598,7 @@ impl CacheDev { cache: LinearDev, origin: LinearDev, cache_block_size: Sectors, + create_options: Option, ) -> DmResult { let table = CacheDev::gen_default_table(&meta, &cache, &origin, cache_block_size); let dev = if device_exists(dm, name)? { @@ -607,7 +613,11 @@ impl CacheDev { device_match(dm, &dev, uuid)?; dev } else { - let dev_info = device_create(dm, name, uuid, &table, DmOptions::private())?; + let options = match create_options { + Some(options) => options, + None => DmOptions::private(), + }; + let dev_info = device_create(dm, name, uuid, &table, options)?; CacheDev { dev_info: Box::new(dev_info), meta_dev: meta, @@ -774,7 +784,7 @@ pub fn minimal_cachedev(dm: &DM, paths: &[&Path]) -> CacheDev { meta_length, LinearDevTargetParams::Linear(meta_params), )]; - let meta = LinearDev::setup(dm, &meta_name, None, meta_table).unwrap(); + let meta = LinearDev::setup(dm, &meta_name, None, meta_table, None).unwrap(); let cache_name = test_name("cache-cache").expect("valid format"); let cache_offset = meta_length; @@ -785,7 +795,7 @@ pub fn minimal_cachedev(dm: &DM, paths: &[&Path]) -> CacheDev { cache_length, LinearDevTargetParams::Linear(cache_params), )]; - let cache = LinearDev::setup(dm, &cache_name, None, cache_table).unwrap(); + let cache = LinearDev::setup(dm, &cache_name, None, cache_table, None).unwrap(); let dev2_size = blkdev_size(&OpenOptions::new().read(true).open(paths[1]).unwrap()).sectors(); let dev2 = Device::from(devnode_to_devno(paths[1]).unwrap().unwrap()); @@ -797,7 +807,7 @@ pub fn minimal_cachedev(dm: &DM, paths: &[&Path]) -> CacheDev { dev2_size, LinearDevTargetParams::Linear(origin_params), )]; - let origin = LinearDev::setup(dm, &origin_name, None, origin_table).unwrap(); + let origin = LinearDev::setup(dm, &origin_name, None, origin_table, None).unwrap(); CacheDev::new( dm, @@ -807,6 +817,7 @@ pub fn minimal_cachedev(dm: &DM, paths: &[&Path]) -> CacheDev { cache, origin, MIN_CACHE_BLOCK_SIZE, + None, ) .unwrap() } diff --git a/src/lineardev.rs b/src/lineardev.rs index eaa3acf9..e568743d 100644 --- a/src/lineardev.rs +++ b/src/lineardev.rs @@ -528,6 +528,7 @@ impl LinearDev { name: &DmName, uuid: Option<&DmUuid>, table: Vec>, + create_options: Option, ) -> DmResult { let table = LinearDevTargetTable::new(table); let dev = if device_exists(dm, name)? { @@ -539,7 +540,11 @@ impl LinearDev { device_match(dm, &dev, uuid)?; dev } else { - let dev_info = device_create(dm, name, uuid, &table, DmOptions::private())?; + let options = match create_options { + Some(options) => options, + None => DmOptions::private(), + }; + let dev_info = device_create(dm, name, uuid, &table, options)?; LinearDev { dev_info: Box::new(dev_info), table, @@ -596,6 +601,7 @@ mod tests { &test_name("new").expect("valid format"), None, vec![], + None, ), Err(_) ); @@ -614,7 +620,7 @@ mod tests { Sectors(1), LinearDevTargetParams::Linear(params), )]; - let mut ld = LinearDev::setup(&dm, &name, None, table).unwrap(); + let mut ld = LinearDev::setup(&dm, &name, None, table, None).unwrap(); assert_matches!(ld.set_table(&dm, vec![]), Err(_)); ld.resume(&dm).unwrap(); @@ -634,7 +640,7 @@ mod tests { Sectors(1), LinearDevTargetParams::Linear(params), )]; - let mut ld = LinearDev::setup(&dm, &name, None, table).unwrap(); + let mut ld = LinearDev::setup(&dm, &name, None, table, None).unwrap(); ld.set_name(&dm, &name).unwrap(); assert_eq!(ld.name(), &*name); @@ -655,7 +661,7 @@ mod tests { Sectors(1), LinearDevTargetParams::Linear(params), )]; - let mut ld = LinearDev::setup(&dm, &name, None, table).unwrap(); + let mut ld = LinearDev::setup(&dm, &name, None, table, None).unwrap(); let new_name = test_name("new_name").expect("valid format"); ld.set_name(&dm, &new_name).unwrap(); @@ -689,7 +695,7 @@ mod tests { ]; let range: Sectors = table.iter().map(|s| s.length).sum(); let count = table.len(); - let mut ld = LinearDev::setup(&dm, &name, None, table).unwrap(); + let mut ld = LinearDev::setup(&dm, &name, None, table, None).unwrap(); let table = LinearDev::read_kernel_table(&dm, &DevId::Name(ld.name())) .unwrap() @@ -723,7 +729,7 @@ mod tests { ) }) .collect::>(); - let mut ld = LinearDev::setup(&dm, &name, None, table.clone()).unwrap(); + let mut ld = LinearDev::setup(&dm, &name, None, table.clone(), None).unwrap(); let loaded_table = LinearDev::read_kernel_table(&dm, &DevId::Name(ld.name())).unwrap(); assert!( @@ -747,15 +753,15 @@ mod tests { Sectors(1), LinearDevTargetParams::Linear(params), )]; - let mut ld = LinearDev::setup(&dm, &name, None, table.clone()).unwrap(); + let mut ld = LinearDev::setup(&dm, &name, None, table.clone(), None).unwrap(); let params2 = LinearTargetParams::new(dev, Sectors(1)); let table2 = vec![TargetLine::new( Sectors(0), Sectors(1), LinearDevTargetParams::Linear(params2), )]; - assert_matches!(LinearDev::setup(&dm, &name, None, table2), Err(_)); - assert_matches!(LinearDev::setup(&dm, &name, None, table), Ok(_)); + assert_matches!(LinearDev::setup(&dm, &name, None, table2, None), Err(_)); + assert_matches!(LinearDev::setup(&dm, &name, None, table, None), Ok(_)); ld.teardown(&dm).unwrap(); } @@ -773,8 +779,8 @@ mod tests { Sectors(1), LinearDevTargetParams::Linear(params), )]; - let mut ld = LinearDev::setup(&dm, &name, None, table.clone()).unwrap(); - let ld2 = LinearDev::setup(&dm, &ersatz, None, table); + let mut ld = LinearDev::setup(&dm, &name, None, table.clone(), None).unwrap(); + let ld2 = LinearDev::setup(&dm, &ersatz, None, table, None); assert_matches!(ld2, Ok(_)); ld2.unwrap().teardown(&dm).unwrap(); @@ -794,7 +800,7 @@ mod tests { Sectors(1), LinearDevTargetParams::Linear(params), )]; - let mut ld = LinearDev::setup(&dm, &name, None, table).unwrap(); + let mut ld = LinearDev::setup(&dm, &name, None, table, None).unwrap(); ld.suspend(&dm, DmOptions::default().set_flags(DmFlags::DM_NOFLUSH)) .unwrap(); diff --git a/src/thindev.rs b/src/thindev.rs index 79a9b7ae..50d453ee 100644 --- a/src/thindev.rs +++ b/src/thindev.rs @@ -267,6 +267,7 @@ impl ThinDev { length: Sectors, thin_pool: &ThinPoolDev, thin_id: ThinDevId, + create_options: Option, ) -> DmResult { message(dm, thin_pool, &format!("create_thin {thin_id}"))?; @@ -275,9 +276,14 @@ impl ThinDev { return Err(DmError::Dm(ErrorEnum::Invalid, err_msg.into())); } + let options = match create_options { + Some(options) => options, + None => DmOptions::default(), + }; + let thin_pool_device = thin_pool.device(); let table = ThinDev::gen_default_table(length, thin_pool_device, thin_id); - let dev_info = device_create(dm, name, uuid, &table, DmOptions::default())?; + let dev_info = device_create(dm, name, uuid, &table, options)?; Ok(ThinDev { dev_info: Box::new(dev_info), @@ -301,6 +307,7 @@ impl ThinDev { length: Sectors, thin_pool: &ThinPoolDev, thin_id: ThinDevId, + create_options: Option, ) -> DmResult { let thin_pool_device = thin_pool.device(); let table = ThinDev::gen_default_table(length, thin_pool_device, thin_id); @@ -313,7 +320,11 @@ impl ThinDev { device_match(dm, &dev, uuid)?; dev } else { - let dev_info = device_create(dm, name, uuid, &table, DmOptions::default())?; + let options = match create_options { + Some(options) => options, + None => DmOptions::default(), + }; + let dev_info = device_create(dm, name, uuid, &table, options)?; ThinDev { dev_info: Box::new(dev_info), table, @@ -333,6 +344,7 @@ impl ThinDev { snapshot_uuid: Option<&DmUuid>, thin_pool: &ThinPoolDev, snapshot_thin_id: ThinDevId, + create_options: Option, ) -> DmResult { let source_id = DevId::Name(self.name()); dm.device_suspend( @@ -347,6 +359,10 @@ impl ThinDev { snapshot_thin_id, self.table.table.params.thin_id ), )?; + let options = match create_options { + Some(options) => options, + None => DmOptions::default(), + }; dm.device_suspend(&source_id, DmOptions::default())?; let table = ThinDev::gen_default_table(self.size(), thin_pool.device(), snapshot_thin_id); let dev_info = Box::new(device_create( @@ -354,7 +370,7 @@ impl ThinDev { snapshot_name, snapshot_uuid, &table, - DmOptions::default(), + options, )?); Ok(ThinDev { dev_info, table }) } @@ -451,7 +467,8 @@ mod tests { None, Sectors(0), &tp, - ThinDevId::new_u64(0).expect("is below limit") + ThinDevId::new_u64(0).expect("is below limit"), + None ), Err(_) ); @@ -478,7 +495,8 @@ mod tests { None, td_size, &tp, - ThinDevId::new_u64(0).expect("is below limit") + ThinDevId::new_u64(0).expect("is below limit"), + None ), Err(DmError::Core(Error::Ioctl(_, _, _, _))) ); @@ -502,7 +520,7 @@ mod tests { let id = test_name("name").expect("is valid DM name"); let td_size = MIN_THIN_DEV_SIZE; - let mut td = ThinDev::new(&dm, &id, None, td_size, &tp, thin_id).unwrap(); + let mut td = ThinDev::new(&dm, &id, None, td_size, &tp, thin_id, None).unwrap(); udev_settle().unwrap(); @@ -525,7 +543,7 @@ mod tests { // New thindev w/ same id fails. assert_matches!( - ThinDev::new(&dm, &id, None, td_size, &tp, thin_id), + ThinDev::new(&dm, &id, None, td_size, &tp, thin_id, None), Err(DmError::Core(Error::Ioctl(_, _, _, _))) ); @@ -533,15 +551,21 @@ mod tests { assert!(device_exists(&dm, &id).unwrap()); // Setting up the just created thin dev succeeds. - assert_matches!(ThinDev::setup(&dm, &id, None, td_size, &tp, thin_id), Ok(_)); + assert_matches!( + ThinDev::setup(&dm, &id, None, td_size, &tp, thin_id, None), + Ok(_) + ); udev_settle().unwrap(); // Setting up the just created thin dev once more succeeds. - assert_matches!(ThinDev::setup(&dm, &id, None, td_size, &tp, thin_id), Ok(_)); + assert_matches!( + ThinDev::setup(&dm, &id, None, td_size, &tp, thin_id, None), + Ok(_) + ); // Teardown the thindev, then set it back up. td.teardown(&dm).unwrap(); - let mut td = ThinDev::setup(&dm, &id, None, td_size, &tp, thin_id).unwrap(); + let mut td = ThinDev::setup(&dm, &id, None, td_size, &tp, thin_id, None).unwrap(); udev_settle().unwrap(); td.destroy(&dm, &tp).unwrap(); @@ -590,7 +614,7 @@ mod tests { let thin_id = ThinDevId::new_u64(0).expect("is below limit"); let id = test_name("udev_test_thin_dev").expect("is valid DM name"); - let mut td = ThinDev::new(&dm, &id, None, tp.size(), &tp, thin_id).unwrap(); + let mut td = ThinDev::new(&dm, &id, None, tp.size(), &tp, thin_id, None).unwrap(); udev_settle().unwrap(); let uuid = Uuid::new_v4(); @@ -605,13 +629,13 @@ mod tests { // Teardown the thindev, then set it back up and make sure all is well with udev td.teardown(&dm).unwrap(); - td = ThinDev::setup(&dm, &id, None, tp.size(), &tp, thin_id).unwrap(); + td = ThinDev::setup(&dm, &id, None, tp.size(), &tp, thin_id, None).unwrap(); validate(&uuid, &td.devnode()); // Create a snapshot and make sure we get correct actions in user space WRT udev let ss_id = ThinDevId::new_u64(1).expect("is below limit"); let ss_name = test_name("snap_name").expect("is valid DM name"); - let mut ss = td.snapshot(&dm, &ss_name, None, &tp, ss_id).unwrap(); + let mut ss = td.snapshot(&dm, &ss_name, None, &tp, ss_id, None).unwrap(); udev_settle().unwrap(); let ss_new_uuid = set_new_fs_uuid(&ss.devnode()); @@ -646,7 +670,7 @@ mod tests { // Create new ThinDev as source for snapshot let thin_id = ThinDevId::new_u64(0).expect("is below limit"); let thin_name = test_name("name").expect("is valid DM name"); - let mut td = ThinDev::new(&dm, &thin_name, None, td_size, &tp, thin_id).unwrap(); + let mut td = ThinDev::new(&dm, &thin_name, None, td_size, &tp, thin_id, None).unwrap(); udev_settle().unwrap(); let data_usage_1 = match tp.status(&dm, DmOptions::default()).unwrap() { @@ -660,7 +684,7 @@ mod tests { // Create a snapshot of the source let ss_id = ThinDevId::new_u64(1).expect("is below limit"); let ss_name = test_name("snap_name").expect("is valid DM name"); - let mut ss = td.snapshot(&dm, &ss_name, None, &tp, ss_id).unwrap(); + let mut ss = td.snapshot(&dm, &ss_name, None, &tp, ss_id, None).unwrap(); udev_settle().unwrap(); let data_usage_2 = match tp.status(&dm, DmOptions::default()).unwrap() { @@ -690,7 +714,7 @@ mod tests { let thin_id = ThinDevId::new_u64(0).expect("is below limit"); let thin_name = test_name("name").expect("is valid DM name"); - let mut td = ThinDev::new(&dm, &thin_name, None, tp.size(), &tp, thin_id).unwrap(); + let mut td = ThinDev::new(&dm, &thin_name, None, tp.size(), &tp, thin_id, None).unwrap(); udev_settle().unwrap(); let orig_data_usage = match tp.status(&dm, DmOptions::default()).unwrap() { @@ -763,8 +787,16 @@ mod tests { let thin_id = ThinDevId::new_u64(0).expect("is below limit"); let thin_name = test_name("name").expect("is valid DM name"); - let mut td = - ThinDev::new(&dm, &thin_name, None, Sectors(2 * IEC::Mi), &tp, thin_id).unwrap(); + let mut td = ThinDev::new( + &dm, + &thin_name, + None, + Sectors(2 * IEC::Mi), + &tp, + thin_id, + None, + ) + .unwrap(); udev_settle().unwrap(); let orig_data_usage = match tp.status(&dm, DmOptions::default()).unwrap() { @@ -788,7 +820,7 @@ mod tests { let ss_name = test_name("snap_name").expect("is valid DM name"); let ss_uuid = test_uuid("snap_uuid").expect("is valid DM uuid"); let mut ss = td - .snapshot(&dm, &ss_name, Some(&ss_uuid), &tp, ss_id) + .snapshot(&dm, &ss_name, Some(&ss_uuid), &tp, ss_id, None) .unwrap(); udev_settle().unwrap(); @@ -815,8 +847,16 @@ mod tests { let thin_id = ThinDevId::new_u64(2).expect("is below limit"); let thin_name = test_name("name1").expect("is valid DM name"); - let mut td1 = - ThinDev::new(&dm, &thin_name, None, Sectors(2 * IEC::Gi), &tp, thin_id).unwrap(); + let mut td1 = ThinDev::new( + &dm, + &thin_name, + None, + Sectors(2 * IEC::Gi), + &tp, + thin_id, + None, + ) + .unwrap(); udev_settle().unwrap(); let data_usage_4 = match tp.status(&dm, DmOptions::default()).unwrap() { @@ -853,16 +893,16 @@ mod tests { let thin_id = ThinDevId::new_u64(0).expect("is below limit"); let thin_name = test_name("name").expect("is valid DM name"); - let mut td = ThinDev::new(&dm, &thin_name, None, tp.size(), &tp, thin_id).unwrap(); + let mut td = ThinDev::new(&dm, &thin_name, None, tp.size(), &tp, thin_id, None).unwrap(); td.teardown(&dm).unwrap(); // This should work - let mut td = ThinDev::setup(&dm, &thin_name, None, tp.size(), &tp, thin_id).unwrap(); + let mut td = ThinDev::setup(&dm, &thin_name, None, tp.size(), &tp, thin_id, None).unwrap(); td.destroy(&dm, &tp).unwrap(); // This should fail assert_matches!( - ThinDev::setup(&dm, &thin_name, None, tp.size(), &tp, thin_id), + ThinDev::setup(&dm, &thin_name, None, tp.size(), &tp, thin_id, None), Err(DmError::Core(Error::Ioctl(_, _, _, _))) ); diff --git a/src/thinpooldev.rs b/src/thinpooldev.rs index f8a64ff7..b361a18d 100644 --- a/src/thinpooldev.rs +++ b/src/thinpooldev.rs @@ -449,15 +449,20 @@ impl ThinPoolDev { data_block_size: Sectors, low_water_mark: DataBlocks, feature_args: Vec, + create_options: Option, ) -> DmResult { if device_exists(dm, name)? { let err_msg = format!("thinpooldev {name} already exists"); return Err(DmError::Dm(ErrorEnum::Invalid, err_msg)); } + let options = match create_options { + Some(options) => options, + None => DmOptions::private(), + }; let table = ThinPoolDev::gen_table(&meta, &data, data_block_size, low_water_mark, feature_args); - let dev_info = device_create(dm, name, uuid, &table, DmOptions::private())?; + let dev_info = device_create(dm, name, uuid, &table, options)?; Ok(ThinPoolDev { dev_info: Box::new(dev_info), @@ -498,6 +503,7 @@ impl ThinPoolDev { data_block_size: Sectors, low_water_mark: DataBlocks, feature_args: Vec, + create_options: Option, ) -> DmResult { let table = ThinPoolDev::gen_table(&meta, &data, data_block_size, low_water_mark, feature_args); @@ -512,7 +518,11 @@ impl ThinPoolDev { device_match(dm, &dev, uuid)?; dev } else { - let dev_info = device_create(dm, name, uuid, &table, DmOptions::private())?; + let options = match create_options { + Some(options) => options, + None => DmOptions::private(), + }; + let dev_info = device_create(dm, name, uuid, &table, options)?; ThinPoolDev { dev_info: Box::new(dev_info), meta_dev: meta, @@ -754,6 +764,7 @@ pub fn minimal_thinpool(dm: &DM, path: &Path) -> ThinPoolDev { &test_name("meta").expect("valid format"), None, meta_table, + None, ) .unwrap(); @@ -768,6 +779,7 @@ pub fn minimal_thinpool(dm: &DM, path: &Path) -> ThinPoolDev { &test_name("data").expect("valid format"), None, data_table, + None, ) .unwrap(); @@ -783,6 +795,7 @@ pub fn minimal_thinpool(dm: &DM, path: &Path) -> ThinPoolDev { "no_discard_passdown".to_owned(), "skip_block_zeroing".to_owned(), ], + None, ) .unwrap() } @@ -855,7 +868,7 @@ mod tests { MIN_RECOMMENDED_METADATA_SIZE, LinearDevTargetParams::Linear(meta_params), )]; - let meta = LinearDev::setup(&dm, &meta_name, None, meta_table).unwrap(); + let meta = LinearDev::setup(&dm, &meta_name, None, meta_table, None).unwrap(); let data_name = test_name("data").expect("valid format"); let data_params = LinearTargetParams::new(dev, MIN_RECOMMENDED_METADATA_SIZE); @@ -864,7 +877,7 @@ mod tests { 512u64 * MIN_DATA_BLOCK_SIZE, LinearDevTargetParams::Linear(data_params), )]; - let data = LinearDev::setup(&dm, &data_name, None, data_table).unwrap(); + let data = LinearDev::setup(&dm, &data_name, None, data_table, None).unwrap(); assert_matches!( ThinPoolDev::new( @@ -879,6 +892,7 @@ mod tests { "no_discard_passdown".to_owned(), "skip_block_zeroing".to_owned() ], + None, ), Err(DmError::Core(Error::Ioctl(_, _, _, _))) ); From c9139b0f8144fe13b57daee13a3dc8cc1dbee1c0 Mon Sep 17 00:00:00 2001 From: "Bryn M. Reeves" Date: Thu, 6 Apr 2023 15:00:26 +0100 Subject: [PATCH 2/3] Allow clippy::too_many_arguments for CacheDev new() and setup() --- src/cachedev.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cachedev.rs b/src/cachedev.rs index 1e5388e3..0f86f371 100644 --- a/src/cachedev.rs +++ b/src/cachedev.rs @@ -558,6 +558,7 @@ impl DmDevice for CacheDev { impl CacheDev { /// Construct a new CacheDev with the given data and meta devs. /// Returns an error if the device is already known to the kernel. + #[allow(clippy::too_many_arguments)] pub fn new( dm: &DM, name: &DmName, @@ -590,6 +591,7 @@ impl CacheDev { } /// Set up a cache device from the given metadata and data devices. + #[allow(clippy::too_many_arguments)] pub fn setup( dm: &DM, name: &DmName, From 3f78077f3abf8d169deaee61f4da044661333a0d Mon Sep 17 00:00:00 2001 From: "Bryn M. Reeves" Date: Mon, 24 Apr 2023 15:40:57 +0100 Subject: [PATCH 3/3] Add an additional Option parameter to resume() Allow callers to control DmOptions and udev flags on resume. This allows clients of the crate to explicitly control the flags used on device resume. If no DmOptions is supplied to a call the library reverts to the long-standing default behaviour. --- src/cachedev.rs | 18 +++++++++--------- src/lineardev.rs | 6 +++--- src/shared.rs | 8 ++++++-- src/thindev.rs | 10 +++++++--- src/thinpooldev.rs | 16 ++++++++-------- 5 files changed, 33 insertions(+), 25 deletions(-) diff --git a/src/cachedev.rs b/src/cachedev.rs index 0f86f371..8c122b41 100644 --- a/src/cachedev.rs +++ b/src/cachedev.rs @@ -646,7 +646,7 @@ impl CacheDev { self.suspend(dm, DmOptions::default().set_flags(DmFlags::DM_NOFLUSH))?; self.origin_dev.set_table(dm, table)?; - self.origin_dev.resume(dm)?; + self.origin_dev.resume(dm, None)?; let mut table = self.table.clone(); table.table.length = self.origin_dev.size(); @@ -670,7 +670,7 @@ impl CacheDev { ) -> DmResult<()> { self.suspend(dm, DmOptions::default().set_flags(DmFlags::DM_NOFLUSH))?; self.cache_dev.set_table(dm, table)?; - self.cache_dev.resume(dm)?; + self.cache_dev.resume(dm, None)?; // Reload the table, even though it is unchanged. Otherwise, we // suffer from whacky smq bug documented in the following PR: @@ -693,7 +693,7 @@ impl CacheDev { ) -> DmResult<()> { self.suspend(dm, DmOptions::default().set_flags(DmFlags::DM_NOFLUSH))?; self.meta_dev.set_table(dm, table)?; - self.meta_dev.resume(dm)?; + self.meta_dev.resume(dm, None)?; // Reload the table, even though it is unchanged. Otherwise, we // suffer from whacky smq bug documented in the following PR: @@ -933,7 +933,7 @@ mod tests { LinearDevTargetParams::Linear(cache_params), )); assert_matches!(cache.set_meta_table(&dm, table), Ok(_)); - cache.resume(&dm).unwrap(); + cache.resume(&dm, None).unwrap(); match cache.status(&dm, DmOptions::default()).unwrap() { CacheDevStatus::Working(ref status) => { @@ -987,7 +987,7 @@ mod tests { LinearDevTargetParams::Linear(cache_params), )); assert_matches!(cache.set_cache_table(&dm, cache_table.clone()), Ok(_)); - cache.resume(&dm).unwrap(); + cache.resume(&dm, None).unwrap(); match cache.status(&dm, DmOptions::default()).unwrap() { CacheDevStatus::Working(ref status) => { @@ -1004,7 +1004,7 @@ mod tests { cache_table.pop(); assert_matches!(cache.set_cache_table(&dm, cache_table), Ok(_)); - cache.resume(&dm).unwrap(); + cache.resume(&dm, None).unwrap(); match cache.status(&dm, DmOptions::default()).unwrap() { CacheDevStatus::Working(ref status) => { @@ -1047,7 +1047,7 @@ mod tests { )); cache.set_origin_table(&dm, origin_table).unwrap(); - cache.resume(&dm).unwrap(); + cache.resume(&dm, None).unwrap(); let origin_size = origin_size + dev3_size; assert_eq!(cache.origin_dev.size(), origin_size); @@ -1073,8 +1073,8 @@ mod tests { cache .suspend(&dm, DmOptions::default().set_flags(DmFlags::DM_NOFLUSH)) .unwrap(); - cache.resume(&dm).unwrap(); - cache.resume(&dm).unwrap(); + cache.resume(&dm, None).unwrap(); + cache.resume(&dm, None).unwrap(); cache.teardown(&dm).unwrap(); } diff --git a/src/lineardev.rs b/src/lineardev.rs index e568743d..5f4530e2 100644 --- a/src/lineardev.rs +++ b/src/lineardev.rs @@ -623,7 +623,7 @@ mod tests { let mut ld = LinearDev::setup(&dm, &name, None, table, None).unwrap(); assert_matches!(ld.set_table(&dm, vec![]), Err(_)); - ld.resume(&dm).unwrap(); + ld.resume(&dm, None).unwrap(); ld.teardown(&dm).unwrap(); } @@ -806,8 +806,8 @@ mod tests { .unwrap(); ld.suspend(&dm, DmOptions::default().set_flags(DmFlags::DM_NOFLUSH)) .unwrap(); - ld.resume(&dm).unwrap(); - ld.resume(&dm).unwrap(); + ld.resume(&dm, None).unwrap(); + ld.resume(&dm, None).unwrap(); ld.teardown(&dm).unwrap(); } diff --git a/src/shared.rs b/src/shared.rs index b5b48169..6c05870d 100644 --- a/src/shared.rs +++ b/src/shared.rs @@ -89,8 +89,12 @@ pub trait DmDevice { fn name(&self) -> &DmName; /// Resume I/O on the device. - fn resume(&mut self, dm: &DM) -> DmResult<()> { - dm.device_suspend(&DevId::Name(self.name()), DmOptions::private())?; + fn resume(&mut self, dm: &DM, options: Option) -> DmResult<()> { + let options = match options { + Some(options) => options, + None => DmOptions::private(), + }; + dm.device_suspend(&DevId::Name(self.name()), options)?; Ok(()) } diff --git a/src/thindev.rs b/src/thindev.rs index 50d453ee..b86bfcb5 100644 --- a/src/thindev.rs +++ b/src/thindev.rs @@ -169,8 +169,12 @@ impl DmDevice for ThinDev { name!(self) } - fn resume(&mut self, dm: &DM) -> DmResult<()> { - dm.device_suspend(&DevId::Name(self.name()), DmOptions::default())?; + fn resume(&mut self, dm: &DM, options: Option) -> DmResult<()> { + let options = match options { + Some(options) => options, + None => DmOptions::default(), + }; + dm.device_suspend(&DevId::Name(self.name()), options)?; Ok(()) } @@ -409,7 +413,7 @@ impl ThinDev { let table = ThinDevTargetTable::new(table.start, table.length, table.params); self.suspend(dm, DmOptions::default().set_flags(DmFlags::DM_NOFLUSH))?; self.table_load(dm, &table, DmOptions::default())?; - self.resume(dm)?; + self.resume(dm, Some(DmOptions::default()))?; self.table = table; Ok(()) diff --git a/src/thinpooldev.rs b/src/thinpooldev.rs index b361a18d..41ba366d 100644 --- a/src/thinpooldev.rs +++ b/src/thinpooldev.rs @@ -591,7 +591,7 @@ impl ThinPoolDev { ) -> DmResult<()> { self.suspend(dm, DmOptions::default().set_flags(DmFlags::DM_NOFLUSH))?; self.meta_dev.set_table(dm, table)?; - self.meta_dev.resume(dm)?; + self.meta_dev.resume(dm, None)?; // Reload the table even though it is unchanged. // See comment on CacheDev::set_cache_table for reason. @@ -614,7 +614,7 @@ impl ThinPoolDev { self.suspend(dm, DmOptions::default().set_flags(DmFlags::DM_NOFLUSH))?; self.data_dev.set_table(dm, table)?; - self.data_dev.resume(dm)?; + self.data_dev.resume(dm, None)?; let mut table = self.table.clone(); table.table.length = self.data_dev.size(); @@ -638,7 +638,7 @@ impl ThinPoolDev { self.table_load(dm, &table, DmOptions::default())?; self.table = table; - self.resume(dm)?; + self.resume(dm, None)?; } Ok(()) @@ -653,7 +653,7 @@ impl ThinPoolDev { self.table_load(dm, &table, DmOptions::default())?; self.table = table; - self.resume(dm)?; + self.resume(dm, None)?; } Ok(()) @@ -926,7 +926,7 @@ mod tests { LinearDevTargetParams::Linear(data_params), )); tp.set_data_table(&dm, data_table).unwrap(); - tp.resume(&dm).unwrap(); + tp.resume(&dm, None).unwrap(); match tp.status(&dm, DmOptions::default()).unwrap() { ThinPoolStatus::Working(ref status) => { @@ -967,7 +967,7 @@ mod tests { LinearDevTargetParams::Linear(meta_params), )); tp.set_meta_table(&dm, meta_table).unwrap(); - tp.resume(&dm).unwrap(); + tp.resume(&dm, None).unwrap(); match tp.status(&dm, DmOptions::default()).unwrap() { ThinPoolStatus::Working(ref status) => { @@ -996,8 +996,8 @@ mod tests { .unwrap(); tp.suspend(&dm, DmOptions::default().set_flags(DmFlags::DM_NOFLUSH)) .unwrap(); - tp.resume(&dm).unwrap(); - tp.resume(&dm).unwrap(); + tp.resume(&dm, None).unwrap(); + tp.resume(&dm, None).unwrap(); tp.teardown(&dm).unwrap(); }