Merge pull request #179 from mingnus/2021-06-03-cache-restore-fixes

Minor fixes
This commit is contained in:
Joe Thornber 2021-06-23 07:55:59 +01:00 committed by GitHub
commit cf27a2cf4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 119 additions and 94 deletions

View File

@ -14,51 +14,55 @@ use thinp::report::*;
fn main() { fn main() {
let parser = App::new("cache_check") let parser = App::new("cache_check")
.version(thinp::version::tools_version()) .version(thinp::version::tools_version())
// flags
.arg( .arg(
Arg::with_name("INPUT") Arg::with_name("ASYNC_IO")
.help("Specify the input device to check") .help("Force use of io_uring for synchronous io")
.required(true) .long("async-io")
.index(1), .hidden(true),
)
.arg(
Arg::with_name("SB_ONLY")
.help("Only check the superblock.")
.long("super-block-only")
.value_name("SB_ONLY"),
)
.arg(
Arg::with_name("SKIP_MAPPINGS")
.help("Don't check the mapping array")
.long("skip-mappings")
.value_name("SKIP_MAPPINGS"),
)
.arg(
Arg::with_name("SKIP_HINTS")
.help("Don't check the hint array")
.long("skip-hints")
.value_name("SKIP_HINTS"),
)
.arg(
Arg::with_name("SKIP_DISCARDS")
.help("Don't check the discard bitset")
.long("skip-discards")
.value_name("SKIP_DISCARDS"),
)
.arg(
Arg::with_name("IGNORE_NON_FATAL")
.help("Only return a non-zero exit code if a fatal error is found.")
.long("ignore-non-fatal-errors"),
) )
.arg( .arg(
Arg::with_name("AUTO_REPAIR") Arg::with_name("AUTO_REPAIR")
.help("Auto repair trivial issues.") .help("Auto repair trivial issues.")
.long("auto-repair"), .long("auto-repair"),
) )
.arg(
Arg::with_name("IGNORE_NON_FATAL")
.help("Only return a non-zero exit code if a fatal error is found.")
.long("ignore-non-fatal-errors"),
)
.arg( .arg(
Arg::with_name("QUIET") Arg::with_name("QUIET")
.help("Suppress output messages, return only exit code.") .help("Suppress output messages, return only exit code.")
.short("q") .short("q")
.long("quiet"), .long("quiet"),
)
.arg(
Arg::with_name("SB_ONLY")
.help("Only check the superblock.")
.long("super-block-only"),
)
.arg(
Arg::with_name("SKIP_MAPPINGS")
.help("Don't check the mapping array")
.long("skip-mappings"),
)
.arg(
Arg::with_name("SKIP_HINTS")
.help("Don't check the hint array")
.long("skip-hints"),
)
.arg(
Arg::with_name("SKIP_DISCARDS")
.help("Don't check the discard bitset")
.long("skip-discards"),
)
// arguments
.arg(
Arg::with_name("INPUT")
.help("Specify the input device to check")
.required(true)
.index(1),
); );
let matches = parser.get_matches(); let matches = parser.get_matches();
@ -75,7 +79,7 @@ fn main() {
let opts = CacheCheckOptions { let opts = CacheCheckOptions {
dev: &input_file, dev: &input_file,
async_io: false, async_io: matches.is_present("ASYNC_IO"),
sb_only: matches.is_present("SB_ONLY"), sb_only: matches.is_present("SB_ONLY"),
skip_mappings: matches.is_present("SKIP_MAPPINGS"), skip_mappings: matches.is_present("SKIP_MAPPINGS"),
skip_hints: matches.is_present("SKIP_HINTS"), skip_hints: matches.is_present("SKIP_HINTS"),

View File

@ -11,12 +11,20 @@ fn main() {
let parser = App::new("cache_dump") let parser = App::new("cache_dump")
.version(thinp::version::tools_version()) .version(thinp::version::tools_version())
.about("Dump the cache metadata to stdout in XML format") .about("Dump the cache metadata to stdout in XML format")
// flags
.arg(
Arg::with_name("ASYNC_IO")
.help("Force use of io_uring for synchronous io")
.long("async-io")
.hidden(true),
)
.arg( .arg(
Arg::with_name("REPAIR") Arg::with_name("REPAIR")
.help("Repair the metadata whilst dumping it") .help("Repair the metadata whilst dumping it")
.short("r") .short("r")
.long("repair"), .long("repair"),
) )
// options
.arg( .arg(
Arg::with_name("OUTPUT") Arg::with_name("OUTPUT")
.help("Specify the output file rather than stdout") .help("Specify the output file rather than stdout")
@ -24,6 +32,7 @@ fn main() {
.long("output") .long("output")
.value_name("OUTPUT"), .value_name("OUTPUT"),
) )
// arguments
.arg( .arg(
Arg::with_name("INPUT") Arg::with_name("INPUT")
.help("Specify the input device to dump") .help("Specify the input device to dump")
@ -42,7 +51,7 @@ fn main() {
let opts = CacheDumpOptions { let opts = CacheDumpOptions {
input: input_file, input: input_file,
output: output_file, output: output_file,
async_io: false, async_io: matches.is_present("ASYNC_IO"),
repair: matches.is_present("REPAIR"), repair: matches.is_present("REPAIR"),
}; };

View File

@ -15,6 +15,13 @@ fn main() {
let parser = App::new("cache_restore") let parser = App::new("cache_restore")
.version(thinp::version::tools_version()) .version(thinp::version::tools_version())
.about("Convert XML format metadata to binary.") .about("Convert XML format metadata to binary.")
// flags
.arg(
Arg::with_name("ASYNC_IO")
.help("Force use of io_uring for synchronous io")
.long("async-io")
.hidden(true),
)
.arg( .arg(
Arg::with_name("OVERRIDE_MAPPING_ROOT") Arg::with_name("OVERRIDE_MAPPING_ROOT")
.help("Specify a mapping root to use") .help("Specify a mapping root to use")
@ -22,6 +29,7 @@ fn main() {
.value_name("OVERRIDE_MAPPING_ROOT") .value_name("OVERRIDE_MAPPING_ROOT")
.takes_value(true), .takes_value(true),
) )
// options
.arg( .arg(
Arg::with_name("INPUT") Arg::with_name("INPUT")
.help("Specify the input xml") .help("Specify the input xml")
@ -37,11 +45,6 @@ fn main() {
.long("output") .long("output")
.value_name("OUTPUT") .value_name("OUTPUT")
.required(true), .required(true),
)
.arg(
Arg::with_name("SYNC_IO")
.help("Force use of synchronous io")
.long("sync-io"),
); );
let matches = parser.get_matches(); let matches = parser.get_matches();
@ -66,7 +69,7 @@ fn main() {
let opts = CacheRestoreOptions { let opts = CacheRestoreOptions {
input: &input_file, input: &input_file,
output: &output_file, output: &output_file,
async_io: !matches.is_present("SYNC_IO"), async_io: matches.is_present("ASYNC_IO"),
report, report,
}; };

View File

@ -16,6 +16,28 @@ fn main() {
let parser = App::new("thin_check") let parser = App::new("thin_check")
.version(thinp::version::tools_version()) .version(thinp::version::tools_version())
.about("Validates thin provisioning metadata on a device or file.") .about("Validates thin provisioning metadata on a device or file.")
// flags
.arg(
Arg::with_name("ASYNC_IO")
.help("Force use of io_uring for synchronous io")
.long("async-io")
.hidden(true),
)
.arg(
Arg::with_name("AUTO_REPAIR")
.help("Auto repair trivial issues.")
.long("auto-repair"),
)
.arg(
Arg::with_name("CLEAR_NEEDS_CHECK")
.help("Clears the 'needs_check' flag in the superblock")
.long("clear-needs-check-flag"),
)
.arg(
Arg::with_name("IGNORE_NON_FATAL")
.help("Only return a non-zero exit code if a fatal error is found.")
.long("ignore-non-fatal-errors"),
)
.arg( .arg(
Arg::with_name("QUIET") Arg::with_name("QUIET")
.help("Suppress output messages, return only exit code.") .help("Suppress output messages, return only exit code.")
@ -32,28 +54,7 @@ fn main() {
.help("Don't check the mapping tree") .help("Don't check the mapping tree")
.long("skip-mappings"), .long("skip-mappings"),
) )
.arg( // options
Arg::with_name("AUTO_REPAIR")
.help("Auto repair trivial issues.")
.long("auto-repair"),
)
.arg(
Arg::with_name("IGNORE_NON_FATAL")
.help("Only return a non-zero exit code if a fatal error is found.")
.long("ignore-non-fatal-errors"),
)
.arg(
Arg::with_name("CLEAR_NEEDS_CHECK")
.help("Clears the 'needs_check' flag in the superblock")
.long("clear-needs-check-flag"),
)
.arg(
Arg::with_name("OVERRIDE_MAPPING_ROOT")
.help("Specify a mapping root to use")
.long("override-mapping-root")
.value_name("OVERRIDE_MAPPING_ROOT")
.takes_value(true),
)
.arg( .arg(
Arg::with_name("METADATA_SNAPSHOT") Arg::with_name("METADATA_SNAPSHOT")
.help("Check the metadata snapshot on a live pool") .help("Check the metadata snapshot on a live pool")
@ -61,21 +62,19 @@ fn main() {
.long("metadata-snapshot") .long("metadata-snapshot")
.value_name("METADATA_SNAPSHOT"), .value_name("METADATA_SNAPSHOT"),
) )
.arg(
Arg::with_name("OVERRIDE_MAPPING_ROOT")
.help("Specify a mapping root to use")
.long("override-mapping-root")
.value_name("OVERRIDE_MAPPING_ROOT")
.takes_value(true),
)
// arguments
.arg( .arg(
Arg::with_name("INPUT") Arg::with_name("INPUT")
.help("Specify the input device to check") .help("Specify the input device to check")
.required(true) .required(true)
.index(1), .index(1),
)
.arg(
Arg::with_name("ASYNC_IO")
.help("Force use of io_uring for asynchronous IO")
.long("async-io"),
)
.arg(
Arg::with_name("SYNC_IO")
.help("Force use of synchronous IO (currently the default)")
.long("sync-io"),
); );
let matches = parser.get_matches(); let matches = parser.get_matches();
@ -96,11 +95,6 @@ fn main() {
report = Arc::new(mk_simple_report()); report = Arc::new(mk_simple_report());
} }
if matches.is_present("SYNC_IO") && matches.is_present("ASYNC_IO") {
eprintln!("--sync-io and --async-io may not be used at the same time.");
process::exit(1);
}
let engine: Arc<dyn IoEngine + Send + Sync>; let engine: Arc<dyn IoEngine + Send + Sync>;
if matches.is_present("ASYNC_IO") { if matches.is_present("ASYNC_IO") {

View File

@ -15,6 +15,13 @@ fn main() {
let parser = App::new("thin_dump") let parser = App::new("thin_dump")
.version(thinp::version::tools_version()) .version(thinp::version::tools_version())
.about("Dump thin-provisioning metadata to stdout in XML format") .about("Dump thin-provisioning metadata to stdout in XML format")
// flags
.arg(
Arg::with_name("ASYNC_IO")
.help("Force use of io_uring for synchronous io")
.long("async-io")
.hidden(true),
)
.arg( .arg(
Arg::with_name("QUIET") Arg::with_name("QUIET")
.help("Suppress output messages, return only exit code.") .help("Suppress output messages, return only exit code.")
@ -32,11 +39,7 @@ fn main() {
.help("Do not dump the mappings") .help("Do not dump the mappings")
.long("skip-mappings"), .long("skip-mappings"),
) )
.arg( // options
Arg::with_name("SYNC_IO")
.help("Force use of synchronous io")
.long("sync-io"),
)
.arg( .arg(
Arg::with_name("METADATA_SNAPSHOT") Arg::with_name("METADATA_SNAPSHOT")
.help("Access the metadata snapshot on a live pool") .help("Access the metadata snapshot on a live pool")
@ -51,6 +54,7 @@ fn main() {
.long("output") .long("output")
.value_name("OUTPUT"), .value_name("OUTPUT"),
) )
// arguments
.arg( .arg(
Arg::with_name("INPUT") Arg::with_name("INPUT")
.help("Specify the input device to dump") .help("Specify the input device to dump")
@ -84,7 +88,7 @@ fn main() {
let opts = ThinDumpOptions { let opts = ThinDumpOptions {
input: input_file, input: input_file,
output: output_file, output: output_file,
async_io: !matches.is_present("SYNC_IO"), async_io: matches.is_present("ASYNC_IO"),
report, report,
}; };

View File

@ -15,13 +15,14 @@ fn main() {
let parser = App::new("thin_restore") let parser = App::new("thin_restore")
.version(thinp::version::tools_version()) .version(thinp::version::tools_version())
.about("Convert XML format metadata to binary.") .about("Convert XML format metadata to binary.")
// flags
.arg( .arg(
Arg::with_name("OVERRIDE_MAPPING_ROOT") Arg::with_name("ASYNC_IO")
.help("Specify a mapping root to use") .help("Force use of io_uring for synchronous io")
.long("override-mapping-root") .long("async-io")
.value_name("OVERRIDE_MAPPING_ROOT") .hidden(true),
.takes_value(true),
) )
// options
.arg( .arg(
Arg::with_name("INPUT") Arg::with_name("INPUT")
.help("Specify the input xml") .help("Specify the input xml")
@ -39,9 +40,11 @@ fn main() {
.required(true), .required(true),
) )
.arg( .arg(
Arg::with_name("SYNC_IO") Arg::with_name("OVERRIDE_MAPPING_ROOT")
.help("Force use of synchronous io") .help("Specify a mapping root to use")
.long("sync-io"), .long("override-mapping-root")
.value_name("OVERRIDE_MAPPING_ROOT")
.takes_value(true),
); );
let matches = parser.get_matches(); let matches = parser.get_matches();
@ -66,7 +69,7 @@ fn main() {
let opts = ThinRestoreOptions { let opts = ThinRestoreOptions {
input: &input_file, input: &input_file,
output: &output_file, output: &output_file,
async_io: !matches.is_present("SYNC_IO"), async_io: matches.is_present("ASYNC_IO"),
report, report,
}; };

View File

@ -77,7 +77,7 @@ fn adjust_counts(
let nr_free = ie.nr_free - (end - begin) as u32; let nr_free = ie.nr_free - (end - begin) as u32;
// Read the bitmap // Read the bitmap
let bitmap_block = w.engine.read(ie.blocknr)?; let bitmap_block = w.read(ie.blocknr)?;
let (_, mut bitmap) = Bitmap::unpack(bitmap_block.get_data())?; let (_, mut bitmap) = Bitmap::unpack(bitmap_block.get_data())?;
// Update all the entries // Update all the entries

View File

@ -109,6 +109,14 @@ impl WriteBatcher {
pub fn write(&mut self, b: Block, kind: checksum::BT) -> Result<()> { pub fn write(&mut self, b: Block, kind: checksum::BT) -> Result<()> {
checksum::write_checksum(&mut b.get_data(), kind)?; checksum::write_checksum(&mut b.get_data(), kind)?;
for blk in self.queue.iter().rev() {
if blk.loc == b.loc {
// write hit
blk.get_data().copy_from_slice(b.get_data());
return Ok(());
}
}
if self.queue.len() == self.batch_size { if self.queue.len() == self.batch_size {
let mut tmp = Vec::new(); let mut tmp = Vec::new();
std::mem::swap(&mut tmp, &mut self.queue); std::mem::swap(&mut tmp, &mut self.queue);