]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
feat(rust/commands): introduce Rust-driven `subvolume` sub-CLI
authorRyan Lahfa <bcachefs@lahfa.xyz>
Sat, 27 Jan 2024 03:23:53 +0000 (04:23 +0100)
committerRyan Lahfa <bcachefs@lahfa.xyz>
Sat, 27 Jan 2024 04:15:19 +0000 (05:15 +0100)
This makes use of `BcachefsHandle` to introduce an elegant Rust driven CLI for subvolumes.

Signed-off-by: Ryan Lahfa <bcachefs@lahfa.xyz>
src/bcachefs.rs
src/commands/cmd_subvolume.rs [new file with mode: 0644]
src/commands/mod.rs

index 62bfdbb7b851a37cb2c9239256e36d8d0614ed5d..7aad517e8927bc7ff3330907a083aae8c1a6814a 100644 (file)
@@ -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 (file)
index 0000000..57c679a
--- /dev/null
@@ -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
+}
index e05a0848819e6e8e4f3b1cae6f4664fde08ffe1d..76de7f86dea039b780cb4de20662df5fd28b380c 100644 (file)
@@ -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]