btrfs_cli/inspect/
dump_super.rs1use crate::{Format, Runnable};
2use anyhow::{Context, Result, bail};
3use btrfs_disk::superblock::{self, SUPER_MIRROR_MAX};
4use clap::Parser;
5use std::{fs::File, path::PathBuf};
6
7#[derive(Parser, Debug)]
14pub struct DumpSuperCommand {
15 path: PathBuf,
17
18 #[clap(short = 'f', long)]
20 full: bool,
21
22 #[clap(short = 'a', long)]
24 all: bool,
25
26 #[clap(short = 's', long = "super", value_parser = clap::value_parser!(u32).range(..SUPER_MIRROR_MAX as i64))]
28 mirror: Option<u32>,
29
30 #[clap(short = 'F', long)]
32 force: bool,
33}
34
35impl Runnable for DumpSuperCommand {
36 fn run(&self, _format: Format, _dry_run: bool) -> Result<()> {
37 let mut file = File::open(&self.path).with_context(|| {
38 format!("failed to open '{}'", self.path.display())
39 })?;
40
41 let mirrors: Vec<u32> = if self.all {
42 (0..SUPER_MIRROR_MAX).collect()
43 } else if let Some(m) = self.mirror {
44 vec![m]
45 } else {
46 vec![0]
47 };
48
49 for (i, &mirror) in mirrors.iter().enumerate() {
50 if i > 0 {
51 println!();
52 }
53
54 let offset = superblock::super_mirror_offset(mirror);
55 println!(
56 "superblock: bytenr={offset}, device={}",
57 self.path.display()
58 );
59
60 let sb = match superblock::read_superblock(&mut file, mirror) {
61 Ok(sb) => sb,
62 Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => {
63 println!(
64 "superblock mirror {mirror} beyond end of device, skipping"
65 );
66 continue;
67 }
68 Err(e) => {
69 return Err(e).with_context(|| {
70 format!(
71 "failed to read superblock mirror {mirror} from '{}'",
72 self.path.display()
73 )
74 });
75 }
76 };
77
78 if !sb.magic_is_valid() && !self.force {
79 if self.all {
80 println!(
81 "superblock mirror {mirror} has bad magic, skipping (use -F to force)"
82 );
83 continue;
84 }
85 bail!(
86 "bad magic on superblock mirror {mirror} of '{}' (use -F to force)",
87 self.path.display()
88 );
89 }
90
91 println!(
92 "---------------------------------------------------------"
93 );
94 superblock::print_superblock(&sb, self.full);
95 }
96
97 Ok(())
98 }
99}