From e1d08fc1fcfc3c0a5aecf99f17dae3445e82c761 Mon Sep 17 00:00:00 2001 From: Ryan Lahfa Date: Sat, 27 Jan 2024 04:23:53 +0100 Subject: [PATCH] feat(rust/commands): introduce Rust-driven `subvolume` sub-CLI This makes use of `BcachefsHandle` to introduce an elegant Rust driven CLI for subvolumes. Signed-off-by: Ryan Lahfa --- src/bcachefs.rs | 3 +- src/commands/cmd_subvolume.rs | 63 +++++++++++++++++++++++++++++++++++ src/commands/mod.rs | 2 ++ 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/commands/cmd_subvolume.rs diff --git a/src/bcachefs.rs b/src/bcachefs.rs index 62bfdbb7..7aad517e 100644 --- a/src/bcachefs.rs +++ b/src/bcachefs.rs @@ -7,6 +7,7 @@ use std::ffi::CString; use commands::cmd_completions::cmd_completions; use commands::cmd_list::cmd_list; use commands::cmd_mount::cmd_mount; +use commands::cmd_subvolume::cmd_subvolumes; use commands::logger::SimpleLogger; use bch_bindgen::c; @@ -61,7 +62,6 @@ fn handle_c_command(args: Vec, symlink_cmd: Option<&str>) -> i32 { "set-passphrase" => c::cmd_set_passphrase(argc, argv), "setattr" => c::cmd_setattr(argc, argv), "show-super" => c::cmd_show_super(argc, argv), - "subvolume" => c::subvolume_cmds(argc, argv), "unlock" => c::cmd_unlock(argc, argv), "version" => c::cmd_version(argc, argv), @@ -112,6 +112,7 @@ fn main() { "completions" => cmd_completions(args[1..].to_vec()), "list" => cmd_list(args[1..].to_vec()), "mount" => cmd_mount(args, symlink_cmd), + "subvolume" => cmd_subvolumes(args[1..].to_vec()), _ => handle_c_command(args, symlink_cmd), }; diff --git a/src/commands/cmd_subvolume.rs b/src/commands/cmd_subvolume.rs new file mode 100644 index 00000000..57c679a1 --- /dev/null +++ b/src/commands/cmd_subvolume.rs @@ -0,0 +1,63 @@ +use std::path::PathBuf; + +use bch_bindgen::c::BCH_SUBVOL_SNAPSHOT_RO; +use clap::{Parser, Subcommand}; + +use crate::wrappers::handle::BcachefsHandle; + +#[derive(Parser, Debug)] +pub struct Cli { + #[command(subcommand)] + subcommands: Subcommands, +} + +/// Subvolumes-related commands +#[derive(Subcommand, Debug)] +enum Subcommands { + Create { + /// Paths + targets: Vec + }, + Delete { + /// Path + target: PathBuf + }, + Snapshot { + /// Make snapshot read only + #[arg(long, short = 'r')] + read_only: bool, + source: PathBuf, + dest: PathBuf + } +} + +pub fn cmd_subvolumes(argv: Vec) -> i32 { + let args = Cli::parse_from(argv); + + match args.subcommands { + Subcommands::Create { targets } => { + for target in targets { + if let Some(dirname) = target.parent() { + let fs = unsafe { BcachefsHandle::open(dirname) }; + fs.create_subvolume(target).expect("Failed to create the subvolume"); + } + } + } + , + Subcommands::Delete { target } => { + if let Some(dirname) = target.parent() { + let fs = unsafe { BcachefsHandle::open(dirname) }; + fs.delete_subvolume(target).expect("Failed to delete the subvolume"); + } + }, + Subcommands::Snapshot { read_only, source, dest } => { + if let Some(dirname) = dest.parent() { + let fs = unsafe { BcachefsHandle::open(dirname) }; + + fs.snapshot_subvolume(if read_only { BCH_SUBVOL_SNAPSHOT_RO } else { 0x0 }, source, dest).expect("Failed to snapshot the subvolume"); + } + } + } + + 0 +} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index e05a0848..76de7f86 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -4,6 +4,7 @@ pub mod logger; pub mod cmd_mount; pub mod cmd_list; pub mod cmd_completions; +pub mod cmd_subvolume; #[derive(clap::Parser, Debug)] #[command(name = "bcachefs")] @@ -17,6 +18,7 @@ enum Subcommands { List(cmd_list::Cli), Mount(cmd_mount::Cli), Completions(cmd_completions::Cli), + Subvolume(cmd_subvolume::Cli), } #[macro_export]