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);
}
}
|