2 use bch_bindgen::error;
3 use bch_bindgen::bcachefs;
4 use bch_bindgen::opt_set;
5 use bch_bindgen::fs::Fs;
6 use bch_bindgen::btree::BtreeTrans;
7 use bch_bindgen::btree::BtreeIter;
8 use bch_bindgen::btree::BtreeIterFlags;
10 use colored::Colorize;
11 use std::ffi::{CStr, OsStr, c_int, c_char};
12 use std::os::unix::ffi::OsStrExt;
14 fn list_keys(fs: &Fs, opt: Cli) -> anyhow::Result<()> {
15 let trans = BtreeTrans::new(fs);
16 let mut iter = BtreeIter::new(&trans, opt.btree, opt.start,
17 BtreeIterFlags::ALL_SNAPSHOTS|
18 BtreeIterFlags::PREFETCH);
20 while let Some(k) = iter.peek_and_restart()? {
25 println!("{}", k.to_text(fs));
32 fn list_btree_formats(fs: &Fs, opt: Cli) -> anyhow::Result<()> {
33 let trans = BtreeTrans::new(fs);
38 fn list_btree_nodes(fs: &Fs, opt: Cli) -> anyhow::Result<()> {
39 let trans = BtreeTrans::new(fs);
44 fn list_nodes_ondisk(fs: &Fs, opt: Cli) -> anyhow::Result<()> {
45 let trans = BtreeTrans::new(fs);
50 fn list_nodes_keys(fs: &Fs, opt: Cli) -> anyhow::Result<()> {
51 let trans = BtreeTrans::new(fs);
56 #[derive(Clone, clap::ValueEnum)]
67 /// Btree to list from
68 #[arg(short, long, default_value_t=bcachefs::btree_id::BTREE_ID_extents)]
69 btree: bcachefs::btree_id,
71 /// Btree depth to descend to (0 == leaves)
72 #[arg(short, long, default_value_t=0)]
75 /// Start position to list from
76 #[arg(short, long, default_value="POS_MIN")]
77 start: bcachefs::bpos,
80 #[arg(short, long, default_value="SPOS_MAX")]
83 #[arg(short, long, default_value="keys")]
86 /// Check (fsck) the filesystem first
87 #[arg(short, long, default_value_t=false)]
90 /// Force color on/off. Default: autodetect tty
91 #[arg(short, long, action = clap::ArgAction::Set, default_value_t=atty::is(Stream::Stdout))]
98 #[arg(required(true))]
99 devices: Vec<std::path::PathBuf>,
102 fn cmd_list_inner(opt: Cli) -> anyhow::Result<()> {
103 let mut fs_opts: bcachefs::bch_opts = Default::default();
105 opt_set!(fs_opts, nochanges, 1);
106 opt_set!(fs_opts, norecovery, 1);
107 opt_set!(fs_opts, degraded, 1);
108 opt_set!(fs_opts, errors, bcachefs::bch_error_actions::BCH_ON_ERROR_continue as u8);
111 opt_set!(fs_opts, fix_errors, bcachefs::fsck_err_opts::FSCK_OPT_YES as u8);
112 opt_set!(fs_opts, norecovery, 0);
116 opt_set!(fs_opts, verbose, 1);
119 let fs = Fs::open(&opt.devices, fs_opts)?;
122 Mode::Keys => list_keys(&fs, opt),
123 Mode::Formats => list_btree_formats(&fs, opt),
124 Mode::Nodes => list_btree_nodes(&fs, opt),
125 Mode::NodesOndisk => list_nodes_ondisk(&fs, opt),
126 Mode::NodesKeys => list_nodes_keys(&fs, opt),
131 pub extern "C" fn cmd_rust_list(argc: c_int, argv: *const *const c_char) {
132 let argv: Vec<_> = (0..argc)
133 .map(|i| unsafe { CStr::from_ptr(*argv.add(i as usize)) })
134 .map(|i| OsStr::from_bytes(i.to_bytes()))
137 let opt = Cli::parse_from(argv);
138 colored::control::set_override(opt.colorize);
139 if let Err(e) = cmd_list_inner(opt) {
140 error!("Fatal error: {}", e);