]> git.sesse.net Git - bcachefs-tools-debian/blob - src/commands/cmd_subvolume.rs
fix snapshotting when dst is single component path
[bcachefs-tools-debian] / src / commands / cmd_subvolume.rs
1 use std::path::PathBuf;
2
3 use bch_bindgen::c::BCH_SUBVOL_SNAPSHOT_RO;
4 use clap::{Parser, Subcommand};
5
6 use crate::wrappers::handle::BcachefsHandle;
7
8 #[derive(Parser, Debug)]
9 pub struct Cli {
10     #[command(subcommand)]
11     subcommands: Subcommands,
12 }
13
14 /// Subvolumes-related commands
15 #[derive(Subcommand, Debug)]
16 enum Subcommands {
17     Create {
18         /// Paths
19         targets: Vec<PathBuf>
20     },
21     Delete {
22         /// Path
23         target: PathBuf
24     },
25     #[command(allow_missing_positional = true)]
26     Snapshot {
27         /// Make snapshot read only
28         #[arg(long, short = 'r')]
29         read_only: bool,
30         source: Option<PathBuf>,
31         dest: PathBuf
32     }
33 }
34
35 pub fn cmd_subvolumes(argv: Vec<String>) -> i32 {
36     let args = Cli::parse_from(argv);
37
38     match args.subcommands {
39         Subcommands::Create { targets } => {
40             for target in targets {
41                 if let Some(dirname) = target.parent() {
42                     let fs = unsafe { BcachefsHandle::open(dirname) };
43                     fs.create_subvolume(target).expect("Failed to create the subvolume");
44                 }
45             }
46         }
47         ,
48         Subcommands::Delete { target } => {
49             if let Some(dirname) = target.parent() {
50                 let fs = unsafe { BcachefsHandle::open(dirname) };
51                 fs.delete_subvolume(target).expect("Failed to delete the subvolume");
52             }
53         },
54         Subcommands::Snapshot { read_only, source, dest } => {
55             if let Some(dirname) = dest.parent() {
56                 let dot = PathBuf::from(".");
57                 let dir = if dirname.as_os_str().is_empty() { &dot } else { dirname };
58                 let fs = unsafe { BcachefsHandle::open(dir) };
59
60                 fs.snapshot_subvolume(if read_only { BCH_SUBVOL_SNAPSHOT_RO } else { 0x0 }, source, dest).expect("Failed to snapshot the subvolume");
61             }
62         }
63     }
64
65     0
66 }