summaryrefslogtreecommitdiff
path: root/rust-src/src/cmd_list.rs
blob: ea4c93fa99ceb98583b5c46ed617508fefee946b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use atty::Stream;
use bch_bindgen::error;
use bch_bindgen::bcachefs;
use bch_bindgen::fs::Fs;
use bch_bindgen::btree::BtreeTrans;
use bch_bindgen::btree::BtreeIter;
use clap::Parser;
use colored::Colorize;
use std::ffi::{CStr, OsStr, c_int, c_char};
use std::os::unix::ffi::OsStrExt;

fn list_keys(fs: &Fs, opt: Cli) -> anyhow::Result<()> {
    let trans = BtreeTrans::new(fs);
    let mut iter = BtreeIter::new(&trans, opt.btree, opt.start, 1 << 11);

    while let Some(k) = iter.peek_and_restart()? {
        unsafe {
            if (*k.k).p > opt.end {
                break;
            }
        }

        println!("{}", k.to_text(fs));

        iter.advance();
    }

    Ok(())
}

fn list_btree_formats(fs: &Fs, opt: Cli) -> anyhow::Result<()> {
    let trans = BtreeTrans::new(fs);

    Ok(())
}

fn list_btree_nodes(fs: &Fs, opt: Cli) -> anyhow::Result<()> {
    let trans = BtreeTrans::new(fs);

    Ok(())
}

fn list_nodes_ondisk(fs: &Fs, opt: Cli) -> anyhow::Result<()> {
    let trans = BtreeTrans::new(fs);

    Ok(())
}

fn list_nodes_keys(fs: &Fs, opt: Cli) -> anyhow::Result<()> {
    let trans = BtreeTrans::new(fs);

    Ok(())
}

#[derive(Clone, clap::ValueEnum)]
enum Mode {
    Keys,
    Formats,
    Nodes,
    NodesOndisk,
    NodesKeys,
}

#[derive(Parser)]
struct Cli {
    /// Btree to list from
    #[arg(short, long, default_value_t=bcachefs::btree_id::BTREE_ID_extents)]
    btree:      bcachefs::btree_id,

    /// Btree depth to descend to (0 == leaves)
    #[arg(short, long, default_value_t=0)]
    level:      u8,

    /// Start position to list from
    #[arg(short, long, default_value="POS_MIN")]
    start:      bcachefs::bpos,

    /// End position
    #[arg(short, long, default_value="SPOS_MAX")]
    end:        bcachefs::bpos,

    #[arg(short, long, default_value="keys")]
    mode:       Mode,

    /// Check (fsck) the filesystem first
    #[arg(short, long, default_value_t=false)]
    fsck:       bool,

    /// Force color on/off. Default: autodetect tty
    #[arg(short, long, action = clap::ArgAction::Set, default_value_t=atty::is(Stream::Stdout))]
    colorize:   bool,
   
    /// Verbose mode
    #[arg(short, long, action = clap::ArgAction::Count)]
    verbose:    u8,

    #[arg(required(true))]
    devices:    Vec<std::path::PathBuf>,
}

fn cmd_list_inner(opt: Cli) -> anyhow::Result<()> {
    let fs_opts: bcachefs::bch_opts = Default::default();

    let fs = Fs::open(&opt.devices, fs_opts)?;

    match opt.mode {
        Mode::Keys          => list_keys(&fs, opt),
        Mode::Formats       => list_btree_formats(&fs, opt),
        Mode::Nodes         => list_btree_nodes(&fs, opt),
        Mode::NodesOndisk   => list_nodes_ondisk(&fs, opt),
        Mode::NodesKeys     => list_nodes_keys(&fs, opt),
    }
}

#[no_mangle]
pub extern "C" fn cmd_rust_list(argc: c_int, argv: *const *const c_char) {
    let argv: Vec<_> = (0..argc)
        .map(|i| unsafe { CStr::from_ptr(*argv.add(i as usize)) })
        .map(|i| OsStr::from_bytes(i.to_bytes()))
        .collect();

    let opt = Cli::parse_from(argv);
    colored::control::set_override(opt.colorize);
    if let Err(e) = cmd_list_inner(opt) {
        error!("Fatal error: {}", e);
    }
}