Skip to main content

btrfs_cli/subvolume/
flags.rs

1use crate::{Format, Runnable, util::open_path};
2use anyhow::{Context, Result};
3use btrfs_uapi::subvolume::{
4    SubvolumeFlags, subvolume_flags_get, subvolume_flags_set,
5};
6use clap::Parser;
7use std::{os::unix::io::AsFd, path::PathBuf};
8
9/// Wrapper around SubvolumeFlags that implements FromStr for clap parsing.
10#[derive(Debug, Clone, Copy)]
11pub struct ParsedSubvolumeFlags(SubvolumeFlags);
12
13impl std::str::FromStr for ParsedSubvolumeFlags {
14    type Err = String;
15
16    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
17        match s {
18            "readonly" => Ok(Self(SubvolumeFlags::RDONLY)),
19            "-" | "" | "none" => Ok(Self(SubvolumeFlags::empty())),
20            _ => Err(format!("unknown flag '{s}'; expected 'readonly' or '-'")),
21        }
22    }
23}
24
25/// Show the flags of a subvolume
26#[derive(Parser, Debug)]
27pub struct SubvolumeGetFlagsCommand {
28    /// Path to a subvolume
29    pub path: PathBuf,
30}
31
32impl Runnable for SubvolumeGetFlagsCommand {
33    fn run(&self, _format: Format, _dry_run: bool) -> Result<()> {
34        let file = open_path(&self.path)?;
35
36        let flags = subvolume_flags_get(file.as_fd()).with_context(|| {
37            format!("failed to get flags for '{}'", self.path.display())
38        })?;
39
40        println!("{flags}");
41
42        Ok(())
43    }
44}
45
46/// Set the flags of a subvolume
47#[derive(Parser, Debug)]
48pub struct SubvolumeSetFlagsCommand {
49    /// Flags to set ("readonly" or "-" to clear)
50    pub flags: ParsedSubvolumeFlags,
51
52    /// Path to a subvolume
53    pub path: PathBuf,
54}
55
56impl Runnable for SubvolumeSetFlagsCommand {
57    fn run(&self, _format: Format, _dry_run: bool) -> Result<()> {
58        let file = open_path(&self.path)?;
59
60        subvolume_flags_set(file.as_fd(), self.flags.0).with_context(|| {
61            format!("failed to set flags on '{}'", self.path.display())
62        })?;
63
64        println!("Set flags to {} on '{}'", self.flags.0, self.path.display());
65
66        Ok(())
67    }
68}