summaryrefslogtreecommitdiff
path: root/rust-src/src/commands/cmd_list.rs
diff options
context:
space:
mode:
authorThomas Bertschinger <tahbertschinger@gmail.com>2024-01-15 23:41:01 -0700
committerKent Overstreet <kent.overstreet@linux.dev>2024-01-16 01:46:58 -0500
commitfb35dbfdc5a9446fbb856dae5542b23963e28b89 (patch)
tree7f8cac8d202534b8da6a3da464c1671ab0f9e033 /rust-src/src/commands/cmd_list.rs
parent0a284fc4ffcbb46f0a4b921415ef12a9c75fa05c (diff)
remove library from bcachefs-tools Rust package
When bcachefs was a C program that had some functions implemented in Rust, it was necessary to make a static library containing the Rust functions available for the C program to link. Now that bcachefs is a Rust program, that library is no longer needed. Instead, the Rust executable links in libbachefs.a. This patch updates the crate structure to reflect that. The command functions are moved into their own module. There could be a need to create a "libbachefs-tools" library in the future that exposes an API for bcachefs functionality to other userspace programs. That will be a different, external API as opposed to the previous library functions which were an internal API for the bcachefs tool itself. Signed-off-by: Thomas Bertschinger <tahbertschinger@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'rust-src/src/commands/cmd_list.rs')
-rw-r--r--rust-src/src/commands/cmd_list.rs168
1 files changed, 168 insertions, 0 deletions
diff --git a/rust-src/src/commands/cmd_list.rs b/rust-src/src/commands/cmd_list.rs
new file mode 100644
index 00000000..cb352916
--- /dev/null
+++ b/rust-src/src/commands/cmd_list.rs
@@ -0,0 +1,168 @@
+use atty::Stream;
+use log::{error};
+use bch_bindgen::bcachefs;
+use bch_bindgen::opt_set;
+use bch_bindgen::fs::Fs;
+use bch_bindgen::bkey::BkeySC;
+use bch_bindgen::btree::BtreeTrans;
+use bch_bindgen::btree::BtreeIter;
+use bch_bindgen::btree::BtreeNodeIter;
+use bch_bindgen::btree::BtreeIterFlags;
+use clap::{Parser};
+
+fn list_keys(fs: &Fs, opt: Cli) -> anyhow::Result<()> {
+ let trans = BtreeTrans::new(fs);
+ let mut iter = BtreeIter::new(&trans, opt.btree, opt.start,
+ BtreeIterFlags::ALL_SNAPSHOTS|
+ BtreeIterFlags::PREFETCH);
+
+ while let Some(k) = iter.peek_and_restart()? {
+ 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);
+ let mut iter = BtreeNodeIter::new(&trans, opt.btree, opt.start,
+ 0, opt.level,
+ BtreeIterFlags::PREFETCH);
+
+ while let Some(b) = iter.peek_and_restart()? {
+ if b.key.k.p > opt.end {
+ break;
+ }
+
+ println!("{}", b.to_text(fs));
+ iter.advance();
+ }
+
+ Ok(())
+}
+
+fn list_btree_nodes(fs: &Fs, opt: Cli) -> anyhow::Result<()> {
+ let trans = BtreeTrans::new(fs);
+ let mut iter = BtreeNodeIter::new(&trans, opt.btree, opt.start,
+ 0, opt.level,
+ BtreeIterFlags::PREFETCH);
+
+ while let Some(b) = iter.peek_and_restart()? {
+ if b.key.k.p > opt.end {
+ break;
+ }
+
+ println!("{}", BkeySC::from(&b.key).to_text(fs));
+ iter.advance();
+ }
+
+ Ok(())
+}
+
+fn list_nodes_ondisk(fs: &Fs, opt: Cli) -> anyhow::Result<()> {
+ let trans = BtreeTrans::new(fs);
+ let mut iter = BtreeNodeIter::new(&trans, opt.btree, opt.start,
+ 0, opt.level,
+ BtreeIterFlags::PREFETCH);
+
+ while let Some(b) = iter.peek_and_restart()? {
+ if b.key.k.p > opt.end {
+ break;
+ }
+
+ println!("{}", b.ondisk_to_text(fs));
+ iter.advance();
+ }
+
+ Ok(())
+}
+
+#[derive(Clone, clap::ValueEnum, Debug)]
+enum Mode {
+ Keys,
+ Formats,
+ Nodes,
+ NodesOndisk,
+}
+
+/// List filesystem metadata in textual form
+#[derive(Parser, Debug)]
+pub 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: u32,
+
+ /// 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)]
+ verbose: bool,
+
+ #[arg(required(true))]
+ devices: Vec<std::path::PathBuf>,
+}
+
+fn cmd_list_inner(opt: Cli) -> anyhow::Result<()> {
+ let mut fs_opts: bcachefs::bch_opts = Default::default();
+
+ opt_set!(fs_opts, nochanges, 1);
+ opt_set!(fs_opts, read_only, 1);
+ opt_set!(fs_opts, norecovery, 1);
+ opt_set!(fs_opts, degraded, 1);
+ opt_set!(fs_opts, errors, bcachefs::bch_error_actions::BCH_ON_ERROR_continue as u8);
+
+ if opt.fsck {
+ opt_set!(fs_opts, fix_errors, bcachefs::fsck_err_opts::FSCK_FIX_yes as u8);
+ opt_set!(fs_opts, norecovery, 0);
+ }
+
+ if opt.verbose {
+ opt_set!(fs_opts, verbose, 1);
+ }
+
+ 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),
+ }
+}
+
+pub fn cmd_list(argv: Vec<String>) -> i32 {
+ let opt = Cli::parse_from(argv);
+ colored::control::set_override(opt.colorize);
+ if let Err(e) = cmd_list_inner(opt) {
+ error!("Fatal error: {}", e);
+ 1
+ } else {
+ 0
+ }
+}