btrfs_cli/inspect/
logical_resolve.rs1use crate::{Format, Runnable};
2use anyhow::{Context, Result};
3use clap::Parser;
4use std::{fs::File, os::unix::io::AsFd, path::PathBuf};
5
6#[derive(Parser, Debug)]
8pub struct LogicalResolveCommand {
9 logical: u64,
11
12 path: PathBuf,
14
15 #[clap(short = 'P', long)]
17 skip_paths: bool,
18
19 #[clap(short = 'o', long)]
21 ignore_offset: bool,
22
23 #[clap(short = 's', long)]
25 bufsize: Option<u64>,
26}
27
28impl Runnable for LogicalResolveCommand {
29 fn run(&self, _format: Format, _dry_run: bool) -> Result<()> {
30 let file = File::open(&self.path).with_context(|| {
31 format!("failed to open '{}'", self.path.display())
32 })?;
33 let fd = file.as_fd();
34
35 let results = btrfs_uapi::inode::logical_ino(
36 fd,
37 self.logical,
38 self.ignore_offset,
39 self.bufsize,
40 )
41 .context(
42 "failed to look up logical address (is this a btrfs filesystem?)",
43 )?;
44
45 if results.is_empty() {
46 eprintln!("no results found for logical address {}", self.logical);
47 } else if self.skip_paths {
48 for result in results {
50 println!(
51 "inode {} offset {} root {}",
52 result.inode, result.offset, result.root
53 );
54 }
55 } else {
56 for result in results {
58 match btrfs_uapi::inode::ino_paths(fd, result.inode) {
59 Ok(paths) => {
60 if paths.is_empty() {
61 println!(
62 "inode {} offset {} root {} <no path>",
63 result.inode, result.offset, result.root
64 );
65 } else {
66 for path in paths {
67 println!("{}", path);
68 }
69 }
70 }
71 Err(_) => {
72 println!(
73 "inode {} offset {} root {} <error resolving path>",
74 result.inode, result.offset, result.root
75 );
76 }
77 }
78 }
79 }
80
81 Ok(())
82 }
83}