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')]
17 skip_paths: bool,
18
19 #[clap(short = 'o')]
21 ignore_offset: bool,
22
23 #[clap(short = 's')]
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)
31 .with_context(|| format!("failed to open '{}'", self.path.display()))?;
32 let fd = file.as_fd();
33
34 let results =
35 btrfs_uapi::inode::logical_ino(fd, self.logical, self.ignore_offset, self.bufsize)
36 .context("failed to look up logical address (is this a btrfs filesystem?)")?;
37
38 if results.is_empty() {
39 eprintln!("no results found for logical address {}", self.logical);
40 } else if self.skip_paths {
41 for result in results {
43 println!(
44 "inode {} offset {} root {}",
45 result.inode, result.offset, result.root
46 );
47 }
48 } else {
49 for result in results {
51 match btrfs_uapi::inode::ino_paths(fd, result.inode) {
52 Ok(paths) => {
53 if paths.is_empty() {
54 println!(
55 "inode {} offset {} root {} <no path>",
56 result.inode, result.offset, result.root
57 );
58 } else {
59 for path in paths {
60 println!("{}", path);
61 }
62 }
63 }
64 Err(_) => {
65 println!(
66 "inode {} offset {} root {} <error resolving path>",
67 result.inode, result.offset, result.root
68 );
69 }
70 }
71 }
72 }
73
74 Ok(())
75 }
76}