summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRyan Lahfa <bcachefs@lahfa.xyz>2024-01-27 04:23:53 +0100
committerRyan Lahfa <bcachefs@lahfa.xyz>2024-01-27 05:15:19 +0100
commite1d08fc1fcfc3c0a5aecf99f17dae3445e82c761 (patch)
tree019e28408dbc0f5616b731524a046bd059503d20 /src
parent9282cb953ce034567cce67336947b731a770f71a (diff)
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 <bcachefs@lahfa.xyz>
Diffstat (limited to 'src')
-rw-r--r--src/bcachefs.rs3
-rw-r--r--src/commands/cmd_subvolume.rs63
-rw-r--r--src/commands/mod.rs2
3 files changed, 67 insertions, 1 deletions
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<String>, 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<PathBuf>
+ },
+ 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<String>) -> 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]