]> git.proxmox.com Git - proxmox-backup.git/commitdiff
turn pxar::flags into bitflags, pxar::Flags
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Wed, 10 Jun 2020 09:03:42 +0000 (11:03 +0200)
committerWolfgang Bumiller <w.bumiller@proxmox.com>
Wed, 10 Jun 2020 09:05:53 +0000 (11:05 +0200)
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
src/backup/catalog_shell.rs
src/bin/proxmox-backup-client.rs
src/bin/pxar.rs
src/client/pxar_backup_stream.rs
src/pxar/create.rs
src/pxar/extract.rs
src/pxar/flags.rs
src/pxar/metadata.rs
src/pxar/mod.rs
tests/catar.rs

index 86bf1fc4037a4fd7c6117a21e3b4fe7d9e789843..87fede0c3e3625e24e5e1720831d751e9342d8c8 100644 (file)
@@ -25,7 +25,7 @@ use crate::backup::catalog::{self, DirEntryAttribute};
 
 // FIXME: Remove looku_self() calls by putting Directory into the dir stack
 use crate::pxar::dir_stack::PxarDirStack;
-use crate::pxar::flags;
+use crate::pxar::Flags;
 use crate::pxar::fuse::{Accessor, FileEntry};
 use crate::pxar::metadata;
 
@@ -977,7 +977,7 @@ impl Shell {
         let pxar_dir_stack = PxarDirStack::new(rootdir, root_meta);
 
         let mut extractor = ExtractorState::new(
-            flags::DEFAULT,
+            Flags::DEFAULT,
             &mut self.catalog,
             dir_stack,
             pxar_dir_stack,
@@ -1010,14 +1010,14 @@ struct ExtractorState<'a> {
     pxar_dir_stack: PxarDirStack,
 
     catalog: &'a mut CatalogReader,
-    feature_flags: u64,
+    feature_flags: Flags,
     match_list: &'a [MatchEntry],
     accessor: &'a Accessor,
 }
 
 impl<'a> ExtractorState<'a> {
     pub fn new(
-        feature_flags: u64,
+        feature_flags: Flags,
         catalog: &'a mut CatalogReader,
         dir_stack: Vec<PathStackEntry>,
         pxar_dir_stack: PxarDirStack,
@@ -1198,7 +1198,7 @@ impl<'a> ExtractorState<'a> {
                 }
 
                 metadata::apply_with_path(
-                    flags::DEFAULT,
+                    Flags::DEFAULT,
                     entry.metadata(),
                     file.as_raw_fd(),
                     entry.file_name(),
index 29ee562bd0895df775710d89599a5377de3742bb..123ab2b5dbbeefa38c6a9c18c9cce18db26ace98 100644 (file)
@@ -1255,7 +1255,7 @@ async fn restore(param: Value) -> Result<Value, Error> {
                 pxar::decoder::Decoder::from_std(reader)?,
                 Path::new(target),
                 &[],
-                proxmox_backup::pxar::flags::DEFAULT,
+                proxmox_backup::pxar::Flags::DEFAULT,
                 allow_existing_dirs,
                 |path| {
                     if verbose {
index 13677305492ace9a5068ebecc9fe8eb996479fa6..ecd61f11868c41beea409885d1e7fd8a6096ddc4 100644 (file)
@@ -15,12 +15,12 @@ use proxmox::api::cli::*;
 use proxmox::api::api;
 
 use proxmox_backup::tools;
-use proxmox_backup::pxar::{flags, fuse, format_single_line_entry, ENCODER_MAX_ENTRIES};
+use proxmox_backup::pxar::{fuse, format_single_line_entry, ENCODER_MAX_ENTRIES, Flags};
 
 fn extract_archive_from_reader<R: std::io::Read>(
     reader: &mut R,
     target: &str,
-    feature_flags: u64,
+    feature_flags: Flags,
     allow_existing_dirs: bool,
     verbose: bool,
     match_list: &[MatchEntry],
@@ -120,24 +120,24 @@ fn extract_archive(
     no_fifos: bool,
     no_sockets: bool,
 ) -> Result<(), Error> {
-    let mut feature_flags = flags::DEFAULT;
+    let mut feature_flags = Flags::DEFAULT;
     if no_xattrs {
-        feature_flags ^= flags::WITH_XATTRS;
+        feature_flags ^= Flags::WITH_XATTRS;
     }
     if no_fcaps {
-        feature_flags ^= flags::WITH_FCAPS;
+        feature_flags ^= Flags::WITH_FCAPS;
     }
     if no_acls {
-        feature_flags ^= flags::WITH_ACL;
+        feature_flags ^= Flags::WITH_ACL;
     }
     if no_device_nodes {
-        feature_flags ^= flags::WITH_DEVICE_NODES;
+        feature_flags ^= Flags::WITH_DEVICE_NODES;
     }
     if no_fifos {
-        feature_flags ^= flags::WITH_FIFOS;
+        feature_flags ^= Flags::WITH_FIFOS;
     }
     if no_sockets {
-        feature_flags ^= flags::WITH_SOCKETS;
+        feature_flags ^= Flags::WITH_SOCKETS;
     }
 
     let pattern = pattern.unwrap_or_else(Vec::new);
@@ -308,24 +308,24 @@ fn create_archive(
         .open(archive)?;
 
     let writer = std::io::BufWriter::with_capacity(1024 * 1024, file);
-    let mut feature_flags = flags::DEFAULT;
+    let mut feature_flags = Flags::DEFAULT;
     if no_xattrs {
-        feature_flags ^= flags::WITH_XATTRS;
+        feature_flags ^= Flags::WITH_XATTRS;
     }
     if no_fcaps {
-        feature_flags ^= flags::WITH_FCAPS;
+        feature_flags ^= Flags::WITH_FCAPS;
     }
     if no_acls {
-        feature_flags ^= flags::WITH_ACL;
+        feature_flags ^= Flags::WITH_ACL;
     }
     if no_device_nodes {
-        feature_flags ^= flags::WITH_DEVICE_NODES;
+        feature_flags ^= Flags::WITH_DEVICE_NODES;
     }
     if no_fifos {
-        feature_flags ^= flags::WITH_FIFOS;
+        feature_flags ^= Flags::WITH_FIFOS;
     }
     if no_sockets {
-        feature_flags ^= flags::WITH_SOCKETS;
+        feature_flags ^= Flags::WITH_SOCKETS;
     }
 
     let writer = pxar::encoder::sync::StandardWriter::new(writer);
index 11f5d924e1fee1bd62e8f7d7f7ec619837d1ef26..7ccca4f0c659890cd2697489738e553409df02db 100644 (file)
@@ -67,7 +67,7 @@ impl PxarBackupStream {
                         dir,
                         writer,
                         patterns,
-                        crate::pxar::flags::DEFAULT,
+                        crate::pxar::Flags::DEFAULT,
                         device_set,
                         skip_lost_and_found,
                         |_| Ok(()),
index 2e403229491e6d4767b187d573663e0f4fd83f52..90b1d00cfbc968057c3e1a451c2e6ad6ffaa1b5b 100644 (file)
@@ -20,7 +20,7 @@ use proxmox::sys::error::SysError;
 use proxmox::tools::fd::RawFdNum;
 
 use crate::pxar::catalog::BackupCatalogWriter;
-use crate::pxar::flags;
+use crate::pxar::Flags;
 use crate::pxar::tools::assert_single_path_component;
 use crate::tools::{acl, fs, xattr, Fd};
 
@@ -86,9 +86,8 @@ struct HardLinkInfo {
 }
 
 struct Archiver<'a, 'b> {
-    /// FIXME: use bitflags!() for feature_flags
-    feature_flags: u64,
-    fs_feature_flags: u64,
+    feature_flags: Flags,
+    fs_feature_flags: Flags,
     fs_magic: i64,
     patterns: &'a [MatchEntry],
     callback: &'a mut dyn FnMut(&Path) -> Result<(), Error>,
@@ -107,7 +106,7 @@ pub fn create_archive<T, F>(
     source_dir: Dir,
     mut writer: T,
     mut patterns: Vec<MatchEntry>,
-    feature_flags: u64,
+    feature_flags: Flags,
     mut device_set: Option<HashSet<u64>>,
     skip_lost_and_found: bool,
     mut callback: F,
@@ -123,7 +122,7 @@ where
         bail!("refusing to backup a virtual file system");
     }
 
-    let fs_feature_flags = flags::feature_flags_from_magic(fs_magic);
+    let fs_feature_flags = Flags::from_magic(fs_magic);
 
     let stat = nix::sys::stat::fstat(source_dir.as_raw_fd())?;
     let metadata = get_metadata(
@@ -176,7 +175,9 @@ struct FileListEntry {
 }
 
 impl<'a, 'b> Archiver<'a, 'b> {
-    fn flags(&self) -> u64 {
+    /// Get the currently effective feature flags. (Requested flags masked by the file system
+    /// feature flags).
+    fn flags(&self) -> Flags {
         self.feature_flags & self.fs_feature_flags
     }
 
@@ -447,7 +448,7 @@ impl<'a, 'b> Archiver<'a, 'b> {
         let mut skip_contents = false;
         if old_st_dev != stat.st_dev {
             self.fs_magic = detect_fs_type(dir.as_raw_fd())?;
-            self.fs_feature_flags = flags::feature_flags_from_magic(self.fs_magic);
+            self.fs_feature_flags = Flags::from_magic(self.fs_magic);
             self.current_st_dev = stat.st_dev;
 
             if is_virtual_file_system(self.fs_magic) {
@@ -511,7 +512,7 @@ impl<'a, 'b> Archiver<'a, 'b> {
     }
 }
 
-fn get_metadata(fd: RawFd, stat: &FileStat, flags: u64, fs_magic: i64) -> Result<Metadata, Error> {
+fn get_metadata(fd: RawFd, stat: &FileStat, flags: Flags, fs_magic: i64) -> Result<Metadata, Error> {
     // required for some of these
     let proc_path = Path::new("/proc/self/fd/").join(fd.to_string());
 
@@ -543,8 +544,8 @@ fn errno_is_unsupported(errno: Errno) -> bool {
     }
 }
 
-fn get_fcaps(meta: &mut Metadata, fd: RawFd, flags: u64) -> Result<(), Error> {
-    if 0 == (flags & flags::WITH_FCAPS) {
+fn get_fcaps(meta: &mut Metadata, fd: RawFd, flags: Flags) -> Result<(), Error> {
+    if flags.contains(Flags::WITH_FCAPS) {
         return Ok(());
     }
 
@@ -564,9 +565,9 @@ fn get_xattr_fcaps_acl(
     meta: &mut Metadata,
     fd: RawFd,
     proc_path: &Path,
-    flags: u64,
+    flags: Flags,
 ) -> Result<(), Error> {
-    if 0 == (flags & flags::WITH_XATTRS) {
+    if flags.contains(Flags::WITH_XATTRS) {
         return Ok(());
     }
 
@@ -617,7 +618,7 @@ fn get_chattr(metadata: &mut Metadata, fd: RawFd) -> Result<(), Error> {
         Err(err) => bail!("failed to read file attributes: {}", err),
     }
 
-    metadata.stat.flags |= flags::feature_flags_from_chattr(attr as u32);
+    metadata.stat.flags |= Flags::from_chattr(attr as u32).bits();
 
     Ok(())
 }
@@ -639,7 +640,7 @@ fn get_fat_attr(metadata: &mut Metadata, fd: RawFd, fs_magic: i64) -> Result<(),
         Err(err) => bail!("failed to read fat attributes: {}", err),
     }
 
-    metadata.stat.flags |= flags::feature_flags_from_fat_attr(attr);
+    metadata.stat.flags |= Flags::from_fat_attr(attr).bits();
 
     Ok(())
 }
@@ -648,14 +649,14 @@ fn get_fat_attr(metadata: &mut Metadata, fd: RawFd, fs_magic: i64) -> Result<(),
 fn get_quota_project_id(
     metadata: &mut Metadata,
     fd: RawFd,
-    flags: u64,
+    flags: Flags,
     magic: i64,
 ) -> Result<(), Error> {
     if !(metadata.is_dir() || metadata.is_regular_file()) {
         return Ok(());
     }
 
-    if 0 == (flags & flags::WITH_QUOTA_PROJID) {
+    if flags.contains(Flags::WITH_QUOTA_PROJID) {
         return Ok(());
     }
 
@@ -689,8 +690,8 @@ fn get_quota_project_id(
     Ok(())
 }
 
-fn get_acl(metadata: &mut Metadata, proc_path: &Path, flags: u64) -> Result<(), Error> {
-    if 0 == (flags & flags::WITH_ACL) {
+fn get_acl(metadata: &mut Metadata, proc_path: &Path, flags: Flags) -> Result<(), Error> {
+    if flags.contains(Flags::WITH_ACL) {
         return Ok(());
     }
 
index 52ed4c8ca6661bec01d1d817ea2dbb79a9b09569..2905b7de6c3b3d870c8e713a90d31a44acdc1731 100644 (file)
@@ -20,20 +20,19 @@ use proxmox::c_result;
 use proxmox::tools::fs::{create_path, CreateOptions};
 
 use crate::pxar::dir_stack::PxarDirStack;
-use crate::pxar::flags;
+use crate::pxar::Flags;
 use crate::pxar::metadata;
 
 struct Extractor<'a> {
-    /// FIXME: use bitflags!() for feature_flags
-    feature_flags: u64,
+    feature_flags: Flags,
     allow_existing_dirs: bool,
     callback: &'a mut dyn FnMut(&Path),
     dir_stack: PxarDirStack,
 }
 
 impl<'a> Extractor<'a> {
-    fn with_flag(&self, flag: u64) -> bool {
-        flag == (self.feature_flags & flag)
+    fn contains_flags(&self, flag: Flags) -> bool {
+        self.feature_flags.contains(flag)
     }
 }
 
@@ -41,7 +40,7 @@ pub fn extract_archive<T, F>(
     mut decoder: pxar::decoder::Decoder<T>,
     destination: &Path,
     match_list: &[MatchEntry],
-    feature_flags: u64,
+    feature_flags: Flags,
     allow_existing_dirs: bool,
     mut callback: F,
 ) -> Result<(), Error>
@@ -164,7 +163,7 @@ where
                 extractor.extract_hardlink(&file_name, metadata, link.as_os_str())
             }
             (true, EntryKind::Device(dev)) => {
-                if extractor.with_flag(flags::WITH_DEVICE_NODES) {
+                if extractor.contains_flags(Flags::WITH_DEVICE_NODES) {
                     extractor.callback(entry.path());
                     extractor.extract_device(&file_name, metadata, dev)
                 } else {
@@ -172,7 +171,7 @@ where
                 }
             }
             (true, EntryKind::Fifo) => {
-                if extractor.with_flag(flags::WITH_FIFOS) {
+                if extractor.contains_flags(Flags::WITH_FIFOS) {
                     extractor.callback(entry.path());
                     extractor.extract_special(&file_name, metadata, 0)
                 } else {
@@ -180,7 +179,7 @@ where
                 }
             }
             (true, EntryKind::Socket) => {
-                if extractor.with_flag(flags::WITH_SOCKETS) {
+                if extractor.contains_flags(Flags::WITH_SOCKETS) {
                     extractor.callback(entry.path());
                     extractor.extract_special(&file_name, metadata, 0)
                 } else {
index 7395beefdf2295814e22c9e5e1becff0af5ad99c..2e81d251aec3c6ecd36b018770a4f832fa5918e0 100644 (file)
 //! Flags for known supported features for a given filesystem can be derived
 //! from the superblocks magic number.
 
-// FIXME: use bitflags!() here!
+use bitflags::bitflags;
 
-/// FAT-style 2s time granularity
-pub const WITH_2SEC_TIME: u64                   = 0x40;
-/// Preserve read only flag of files
-pub const WITH_READ_ONLY: u64                   = 0x80;
-/// Preserve unix permissions
-pub const WITH_PERMISSIONS: u64                 = 0x100;
-/// Include symbolik links
-pub const WITH_SYMLINKS: u64                    = 0x200;
-/// Include device nodes
-pub const WITH_DEVICE_NODES: u64                = 0x400;
-/// Include FIFOs
-pub const WITH_FIFOS: u64                       = 0x800;
-/// Include Sockets
-pub const WITH_SOCKETS: u64                     = 0x1000;
+bitflags! {
+    pub struct Flags: u64 {
+        /// FAT-style 2s time granularity
+        const WITH_2SEC_TIME                   = 0x40;
+        /// Preserve read only flag of files
+        const WITH_READ_ONLY                   = 0x80;
+        /// Preserve unix permissions
+        const WITH_PERMISSIONS                 = 0x100;
+        /// Include symbolik links
+        const WITH_SYMLINKS                    = 0x200;
+        /// Include device nodes
+        const WITH_DEVICE_NODES                = 0x400;
+        /// Include FIFOs
+        const WITH_FIFOS                       = 0x800;
+        /// Include Sockets
+        const WITH_SOCKETS                     = 0x1000;
 
-/// Preserve DOS file flag `HIDDEN`
-pub const WITH_FLAG_HIDDEN: u64                 = 0x2000;
-/// Preserve DOS file flag `SYSTEM`
-pub const WITH_FLAG_SYSTEM: u64                 = 0x4000;
-/// Preserve DOS file flag `ARCHIVE`
-pub const WITH_FLAG_ARCHIVE: u64                = 0x8000;
+        /// Preserve DOS file flag `HIDDEN`
+        const WITH_FLAG_HIDDEN                 = 0x2000;
+        /// Preserve DOS file flag `SYSTEM`
+        const WITH_FLAG_SYSTEM                 = 0x4000;
+        /// Preserve DOS file flag `ARCHIVE`
+        const WITH_FLAG_ARCHIVE                = 0x8000;
 
-// chattr() flags
-/// Linux file attribute `APPEND`
-pub const WITH_FLAG_APPEND: u64                 = 0x10000;
-/// Linux file attribute `NOATIME`
-pub const WITH_FLAG_NOATIME: u64                = 0x20000;
-/// Linux file attribute `COMPR`
-pub const WITH_FLAG_COMPR: u64                  = 0x40000;
-/// Linux file attribute `NOCOW`
-pub const WITH_FLAG_NOCOW: u64                  = 0x80000;
-/// Linux file attribute `NODUMP`
-pub const WITH_FLAG_NODUMP: u64                 = 0x0010_0000;
-/// Linux file attribute `DIRSYNC`
-pub const WITH_FLAG_DIRSYNC: u64                = 0x0020_0000;
-/// Linux file attribute `IMMUTABLE`
-pub const WITH_FLAG_IMMUTABLE: u64              = 0x0040_0000;
-/// Linux file attribute `SYNC`
-pub const WITH_FLAG_SYNC: u64                   = 0x0080_0000;
-/// Linux file attribute `NOCOMP`
-pub const WITH_FLAG_NOCOMP: u64                 = 0x0100_0000;
-/// Linux file attribute `PROJINHERIT`
-pub const WITH_FLAG_PROJINHERIT: u64            = 0x0200_0000;
+        // chattr() flags
+        /// Linux file attribute `APPEND`
+        const WITH_FLAG_APPEND                 = 0x10000;
+        /// Linux file attribute `NOATIME`
+        const WITH_FLAG_NOATIME                = 0x20000;
+        /// Linux file attribute `COMPR`
+        const WITH_FLAG_COMPR                  = 0x40000;
+        /// Linux file attribute `NOCOW`
+        const WITH_FLAG_NOCOW                  = 0x80000;
+        /// Linux file attribute `NODUMP`
+        const WITH_FLAG_NODUMP                 = 0x0010_0000;
+        /// Linux file attribute `DIRSYNC`
+        const WITH_FLAG_DIRSYNC                = 0x0020_0000;
+        /// Linux file attribute `IMMUTABLE`
+        const WITH_FLAG_IMMUTABLE              = 0x0040_0000;
+        /// Linux file attribute `SYNC`
+        const WITH_FLAG_SYNC                   = 0x0080_0000;
+        /// Linux file attribute `NOCOMP`
+        const WITH_FLAG_NOCOMP                 = 0x0100_0000;
+        /// Linux file attribute `PROJINHERIT`
+        const WITH_FLAG_PROJINHERIT            = 0x0200_0000;
 
 
-/// Preserve BTRFS subvolume flag
-pub const WITH_SUBVOLUME: u64                   = 0x0400_0000;
-/// Preserve BTRFS read-only subvolume flag
-pub const WITH_SUBVOLUME_RO: u64                = 0x0800_0000;
+        /// Preserve BTRFS subvolume flag
+        const WITH_SUBVOLUME                   = 0x0400_0000;
+        /// Preserve BTRFS read-only subvolume flag
+        const WITH_SUBVOLUME_RO                = 0x0800_0000;
 
-/// Preserve Extended Attribute metadata
-pub const WITH_XATTRS: u64                      = 0x1000_0000;
-/// Preserve Access Control List metadata
-pub const WITH_ACL: u64                         = 0x2000_0000;
-/// Preserve SELinux security context
-pub const WITH_SELINUX: u64                     = 0x4000_0000;
-/// Preserve "security.capability" xattr
-pub const WITH_FCAPS: u64                       = 0x8000_0000;
+        /// Preserve Extended Attribute metadata
+        const WITH_XATTRS                      = 0x1000_0000;
+        /// Preserve Access Control List metadata
+        const WITH_ACL                         = 0x2000_0000;
+        /// Preserve SELinux security context
+        const WITH_SELINUX                     = 0x4000_0000;
+        /// Preserve "security.capability" xattr
+        const WITH_FCAPS                       = 0x8000_0000;
 
-/// Preserve XFS/ext4/ZFS project quota ID
-pub const WITH_QUOTA_PROJID: u64                = 0x0001_0000_0000;
+        /// Preserve XFS/ext4/ZFS project quota ID
+        const WITH_QUOTA_PROJID                = 0x0001_0000_0000;
 
-/// Support ".pxarexclude" files
-pub const EXCLUDE_FILE: u64                     = 0x1000_0000_0000_0000;
-/// Exclude submounts
-pub const EXCLUDE_SUBMOUNTS: u64                = 0x4000_0000_0000_0000;
-/// Exclude entries with chattr flag NODUMP
-pub const EXCLUDE_NODUMP: u64                   = 0x8000_0000_0000_0000;
+        /// Support ".pxarexclude" files
+        const EXCLUDE_FILE                     = 0x1000_0000_0000_0000;
+        /// Exclude submounts
+        const EXCLUDE_SUBMOUNTS                = 0x4000_0000_0000_0000;
+        /// Exclude entries with chattr flag NODUMP
+        const EXCLUDE_NODUMP                   = 0x8000_0000_0000_0000;
 
-/// Definitions of typical feature flags for the *pxar* encoder/decoder.
-/// By this expensive syscalls for unsupported features are avoided.
+        // Definitions of typical feature flags for the *pxar* encoder/decoder.
+        // By this expensive syscalls for unsupported features are avoided.
 
-/// All chattr file attributes
-pub const WITH_CHATTR: u64 =
-    WITH_FLAG_APPEND|
-    WITH_FLAG_NOATIME|
-    WITH_FLAG_COMPR|
-    WITH_FLAG_NOCOW|
-    WITH_FLAG_NODUMP|
-    WITH_FLAG_DIRSYNC|
-    WITH_FLAG_IMMUTABLE|
-    WITH_FLAG_SYNC|
-    WITH_FLAG_NOCOMP|
-    WITH_FLAG_PROJINHERIT;
+        /// All chattr file attributes
+        const WITH_CHATTR =
+            Flags::WITH_FLAG_APPEND.bits() |
+            Flags::WITH_FLAG_NOATIME.bits() |
+            Flags::WITH_FLAG_COMPR.bits() |
+            Flags::WITH_FLAG_NOCOW.bits() |
+            Flags::WITH_FLAG_NODUMP.bits() |
+            Flags::WITH_FLAG_DIRSYNC.bits() |
+            Flags::WITH_FLAG_IMMUTABLE.bits() |
+            Flags::WITH_FLAG_SYNC.bits() |
+            Flags::WITH_FLAG_NOCOMP.bits() |
+            Flags::WITH_FLAG_PROJINHERIT.bits();
 
-/// All FAT file attributes
-pub const WITH_FAT_ATTRS: u64 =
-    WITH_FLAG_HIDDEN|
-    WITH_FLAG_SYSTEM|
-    WITH_FLAG_ARCHIVE;
+        /// All FAT file attributes
+        const WITH_FAT_ATTRS =
+            Flags::WITH_FLAG_HIDDEN.bits() |
+            Flags::WITH_FLAG_SYSTEM.bits() |
+            Flags::WITH_FLAG_ARCHIVE.bits();
 
-/// All bits that may also be exposed via fuse
-pub const WITH_FUSE: u64 =
-    WITH_2SEC_TIME|
-    WITH_READ_ONLY|
-    WITH_PERMISSIONS|
-    WITH_SYMLINKS|
-    WITH_DEVICE_NODES|
-    WITH_FIFOS|
-    WITH_SOCKETS|
-    WITH_FAT_ATTRS|
-    WITH_CHATTR|
-    WITH_XATTRS;
+        /// All bits that may also be exposed via fuse
+        const WITH_FUSE =
+            Flags::WITH_2SEC_TIME.bits() |
+            Flags::WITH_READ_ONLY.bits() |
+            Flags::WITH_PERMISSIONS.bits() |
+            Flags::WITH_SYMLINKS.bits() |
+            Flags::WITH_DEVICE_NODES.bits() |
+            Flags::WITH_FIFOS.bits() |
+            Flags::WITH_SOCKETS.bits() |
+            Flags::WITH_FAT_ATTRS.bits() |
+            Flags::WITH_CHATTR.bits() |
+            Flags::WITH_XATTRS.bits();
 
 
-/// Default feature flags for encoder/decoder
-pub const DEFAULT: u64 =
-    WITH_SYMLINKS|
-    WITH_DEVICE_NODES|
-    WITH_FIFOS|
-    WITH_SOCKETS|
-    WITH_FLAG_HIDDEN|
-    WITH_FLAG_SYSTEM|
-    WITH_FLAG_ARCHIVE|
-    WITH_FLAG_APPEND|
-    WITH_FLAG_NOATIME|
-    WITH_FLAG_COMPR|
-    WITH_FLAG_NOCOW|
-    //WITH_FLAG_NODUMP|
-    WITH_FLAG_DIRSYNC|
-    WITH_FLAG_IMMUTABLE|
-    WITH_FLAG_SYNC|
-    WITH_FLAG_NOCOMP|
-    WITH_FLAG_PROJINHERIT|
-    WITH_SUBVOLUME|
-    WITH_SUBVOLUME_RO|
-    WITH_XATTRS|
-    WITH_ACL|
-    WITH_SELINUX|
-    WITH_FCAPS|
-    WITH_QUOTA_PROJID|
-    EXCLUDE_NODUMP|
-    EXCLUDE_FILE;
+        /// Default feature flags for encoder/decoder
+        const DEFAULT =
+            Flags::WITH_SYMLINKS.bits() |
+            Flags::WITH_DEVICE_NODES.bits() |
+            Flags::WITH_FIFOS.bits() |
+            Flags::WITH_SOCKETS.bits() |
+            Flags::WITH_FLAG_HIDDEN.bits() |
+            Flags::WITH_FLAG_SYSTEM.bits() |
+            Flags::WITH_FLAG_ARCHIVE.bits() |
+            Flags::WITH_FLAG_APPEND.bits() |
+            Flags::WITH_FLAG_NOATIME.bits() |
+            Flags::WITH_FLAG_COMPR.bits() |
+            Flags::WITH_FLAG_NOCOW.bits() |
+            //WITH_FLAG_NODUMP.bits() |
+            Flags::WITH_FLAG_DIRSYNC.bits() |
+            Flags::WITH_FLAG_IMMUTABLE.bits() |
+            Flags::WITH_FLAG_SYNC.bits() |
+            Flags::WITH_FLAG_NOCOMP.bits() |
+            Flags::WITH_FLAG_PROJINHERIT.bits() |
+            Flags::WITH_SUBVOLUME.bits() |
+            Flags::WITH_SUBVOLUME_RO.bits() |
+            Flags::WITH_XATTRS.bits() |
+            Flags::WITH_ACL.bits() |
+            Flags::WITH_SELINUX.bits() |
+            Flags::WITH_FCAPS.bits() |
+            Flags::WITH_QUOTA_PROJID.bits() |
+            Flags::EXCLUDE_NODUMP.bits() |
+            Flags::EXCLUDE_FILE.bits();
+    }
+}
 
-// form /usr/include/linux/fs.h
-const FS_APPEND_FL: u32 =      0x0000_0020;
-const FS_NOATIME_FL: u32 =     0x0000_0080;
-const FS_COMPR_FL: u32 =       0x0000_0004;
-const FS_NOCOW_FL: u32 =       0x0080_0000;
-const FS_NODUMP_FL: u32 =      0x0000_0040;
-const FS_DIRSYNC_FL: u32 =     0x0001_0000;
-const FS_IMMUTABLE_FL: u32 =   0x0000_0010;
-const FS_SYNC_FL: u32 =        0x0000_0008;
-const FS_NOCOMP_FL: u32 =      0x0000_0400;
-const FS_PROJINHERIT_FL: u32 = 0x2000_0000;
+impl Default for Flags {
+    fn default() -> Flags {
+        Flags::DEFAULT
+    }
+}
 
-static CHATTR_MAP: [(u64, u32); 10] = [
-    ( WITH_FLAG_APPEND,      FS_APPEND_FL      ),
-    ( WITH_FLAG_NOATIME,     FS_NOATIME_FL     ),
-    ( WITH_FLAG_COMPR,       FS_COMPR_FL       ),
-    ( WITH_FLAG_NOCOW,       FS_NOCOW_FL       ),
-    ( WITH_FLAG_NODUMP,      FS_NODUMP_FL      ),
-    ( WITH_FLAG_DIRSYNC,     FS_DIRSYNC_FL     ),
-    ( WITH_FLAG_IMMUTABLE,   FS_IMMUTABLE_FL   ),
-    ( WITH_FLAG_SYNC,        FS_SYNC_FL        ),
-    ( WITH_FLAG_NOCOMP,      FS_NOCOMP_FL      ),
-    ( WITH_FLAG_PROJINHERIT, FS_PROJINHERIT_FL ),
-];
+impl Flags {
+    /// Get a set of feature flags from file attributes.
+    pub fn from_chattr(attr: u32) -> Flags {
+        // form /usr/include/linux/fs.h
+        const FS_APPEND_FL: u32 =      0x0000_0020;
+        const FS_NOATIME_FL: u32 =     0x0000_0080;
+        const FS_COMPR_FL: u32 =       0x0000_0004;
+        const FS_NOCOW_FL: u32 =       0x0080_0000;
+        const FS_NODUMP_FL: u32 =      0x0000_0040;
+        const FS_DIRSYNC_FL: u32 =     0x0001_0000;
+        const FS_IMMUTABLE_FL: u32 =   0x0000_0010;
+        const FS_SYNC_FL: u32 =        0x0000_0008;
+        const FS_NOCOMP_FL: u32 =      0x0000_0400;
+        const FS_PROJINHERIT_FL: u32 = 0x2000_0000;
 
-pub fn feature_flags_from_chattr(attr: u32) -> u64 {
+        const CHATTR_MAP: [(Flags, u32); 10] = [
+            ( Flags::WITH_FLAG_APPEND,      FS_APPEND_FL      ),
+            ( Flags::WITH_FLAG_NOATIME,     FS_NOATIME_FL     ),
+            ( Flags::WITH_FLAG_COMPR,       FS_COMPR_FL       ),
+            ( Flags::WITH_FLAG_NOCOW,       FS_NOCOW_FL       ),
+            ( Flags::WITH_FLAG_NODUMP,      FS_NODUMP_FL      ),
+            ( Flags::WITH_FLAG_DIRSYNC,     FS_DIRSYNC_FL     ),
+            ( Flags::WITH_FLAG_IMMUTABLE,   FS_IMMUTABLE_FL   ),
+            ( Flags::WITH_FLAG_SYNC,        FS_SYNC_FL        ),
+            ( Flags::WITH_FLAG_NOCOMP,      FS_NOCOMP_FL      ),
+            ( Flags::WITH_FLAG_PROJINHERIT, FS_PROJINHERIT_FL ),
+        ];
 
-    let mut flags = 0u64;
+        let mut flags = Flags::empty();
 
-    for (fe_flag, fs_flag) in &CHATTR_MAP {
-        if (attr & fs_flag) != 0 { flags |= fe_flag; }
-    }
+        for (fe_flag, fs_flag) in &CHATTR_MAP {
+            if (attr & fs_flag) != 0 {
+                flags |= *fe_flag;
+            }
+        }
 
-    flags
-}
+        flags
+    }
 
-// from /usr/include/linux/msdos_fs.h
-const ATTR_HIDDEN: u32 =      2;
-const ATTR_SYS: u32 =         4;
-const ATTR_ARCH: u32 =       32;
+    /// Get a set of feature flags from FAT attributes.
+    pub fn from_fat_attr(attr: u32) -> Flags {
+        // from /usr/include/linux/msdos_fs.h
+        const ATTR_HIDDEN: u32 =      2;
+        const ATTR_SYS: u32 =         4;
+        const ATTR_ARCH: u32 =       32;
 
-static FAT_ATTR_MAP: [(u64, u32); 3] = [
-    WITH_FLAG_HIDDEN,  ATTR_HIDDEN ),
-    WITH_FLAG_SYSTEM,  ATTR_SYS    ),
-    WITH_FLAG_ARCHIVE, ATTR_ARCH   ),
-];
+        const FAT_ATTR_MAP: [(Flags, u32); 3] = [
+            ( Flags::WITH_FLAG_HIDDEN,  ATTR_HIDDEN ),
+            ( Flags::WITH_FLAG_SYSTEM,  ATTR_SYS    ),
+            ( Flags::WITH_FLAG_ARCHIVE, ATTR_ARCH   ),
+        ];
 
-pub fn feature_flags_from_fat_attr(attr: u32) -> u64 {
+        let mut flags = Flags::empty();
 
-    let mut flags = 0u64;
+        for (fe_flag, fs_flag) in &FAT_ATTR_MAP {
+            if (attr & fs_flag) != 0 {
+                flags |= *fe_flag;
+            }
+        }
 
-    for (fe_flag, fs_flag) in &FAT_ATTR_MAP {
-        if (attr & fs_flag) != 0 { flags |= fe_flag; }
+        flags
     }
 
-    flags
-}
-
-
-/// Return the supported *pxar* feature flags based on the magic number of the filesystem.
-pub fn feature_flags_from_magic(magic: i64) -> u64 {
-    use proxmox::sys::linux::magic::*;
-    match magic {
-        MSDOS_SUPER_MAGIC => {
-            WITH_2SEC_TIME|
-            WITH_READ_ONLY|
-            WITH_FAT_ATTRS
-        },
-        EXT4_SUPER_MAGIC => {
-            WITH_2SEC_TIME|
-            WITH_READ_ONLY|
-            WITH_PERMISSIONS|
-            WITH_SYMLINKS|
-            WITH_DEVICE_NODES|
-            WITH_FIFOS|
-            WITH_SOCKETS|
-            WITH_FLAG_APPEND|
-            WITH_FLAG_NOATIME|
-            WITH_FLAG_NODUMP|
-            WITH_FLAG_DIRSYNC|
-            WITH_FLAG_IMMUTABLE|
-            WITH_FLAG_SYNC|
-            WITH_XATTRS|
-            WITH_ACL|
-            WITH_SELINUX|
-            WITH_FCAPS|
-            WITH_QUOTA_PROJID
-        },
-        XFS_SUPER_MAGIC => {
-            WITH_2SEC_TIME|
-            WITH_READ_ONLY|
-            WITH_PERMISSIONS|
-            WITH_SYMLINKS|
-            WITH_DEVICE_NODES|
-            WITH_FIFOS|
-            WITH_SOCKETS|
-            WITH_FLAG_APPEND|
-            WITH_FLAG_NOATIME|
-            WITH_FLAG_NODUMP|
-            WITH_FLAG_IMMUTABLE|
-            WITH_FLAG_SYNC|
-            WITH_XATTRS|
-            WITH_ACL|
-            WITH_SELINUX|
-            WITH_FCAPS|
-            WITH_QUOTA_PROJID
-        },
-        ZFS_SUPER_MAGIC => {
-            WITH_2SEC_TIME|
-            WITH_READ_ONLY|
-            WITH_PERMISSIONS|
-            WITH_SYMLINKS|
-            WITH_DEVICE_NODES|
-            WITH_FIFOS|
-            WITH_SOCKETS|
-            WITH_FLAG_APPEND|
-            WITH_FLAG_NOATIME|
-            WITH_FLAG_NODUMP|
-            WITH_FLAG_DIRSYNC|
-            WITH_FLAG_IMMUTABLE|
-            WITH_FLAG_SYNC|
-            WITH_XATTRS|
-            WITH_ACL|
-            WITH_SELINUX|
-            WITH_FCAPS|
-            WITH_QUOTA_PROJID
-        },
-        BTRFS_SUPER_MAGIC => {
-            WITH_2SEC_TIME|
-            WITH_READ_ONLY|
-            WITH_PERMISSIONS|
-            WITH_SYMLINKS|
-            WITH_DEVICE_NODES|
-            WITH_FIFOS|
-            WITH_SOCKETS|
-            WITH_FLAG_APPEND|
-            WITH_FLAG_NOATIME|
-            WITH_FLAG_COMPR|
-            WITH_FLAG_NOCOW|
-            WITH_FLAG_NODUMP|
-            WITH_FLAG_DIRSYNC|
-            WITH_FLAG_IMMUTABLE|
-            WITH_FLAG_SYNC|
-            WITH_FLAG_NOCOMP|
-            WITH_XATTRS|
-            WITH_ACL|
-            WITH_SELINUX|
-            WITH_SUBVOLUME|
-            WITH_SUBVOLUME_RO|
-            WITH_FCAPS
-        },
-        TMPFS_MAGIC => {
-            WITH_2SEC_TIME|
-            WITH_READ_ONLY|
-            WITH_PERMISSIONS|
-            WITH_SYMLINKS|
-            WITH_DEVICE_NODES|
-            WITH_FIFOS|
-            WITH_SOCKETS|
-            WITH_ACL|
-            WITH_SELINUX
-        },
-        // FUSE mounts are special as the supported feature set
-        // is not clear a priori.
-        FUSE_SUPER_MAGIC => {
-            WITH_FUSE
-        },
-        _ => {
-            WITH_2SEC_TIME|
-            WITH_READ_ONLY|
-            WITH_PERMISSIONS|
-            WITH_SYMLINKS|
-            WITH_DEVICE_NODES|
-            WITH_FIFOS|
-            WITH_SOCKETS
-        },
+    /// Return the supported *pxar* feature flags based on the magic number of the filesystem.
+    pub fn from_magic(magic: i64) -> Flags {
+        use proxmox::sys::linux::magic::*;
+        match magic {
+            MSDOS_SUPER_MAGIC => {
+                Flags::WITH_2SEC_TIME |
+                Flags::WITH_READ_ONLY |
+                Flags::WITH_FAT_ATTRS
+            },
+            EXT4_SUPER_MAGIC => {
+                Flags::WITH_2SEC_TIME |
+                Flags::WITH_READ_ONLY |
+                Flags::WITH_PERMISSIONS |
+                Flags::WITH_SYMLINKS |
+                Flags::WITH_DEVICE_NODES |
+                Flags::WITH_FIFOS |
+                Flags::WITH_SOCKETS |
+                Flags::WITH_FLAG_APPEND |
+                Flags::WITH_FLAG_NOATIME |
+                Flags::WITH_FLAG_NODUMP |
+                Flags::WITH_FLAG_DIRSYNC |
+                Flags::WITH_FLAG_IMMUTABLE |
+                Flags::WITH_FLAG_SYNC |
+                Flags::WITH_XATTRS |
+                Flags::WITH_ACL |
+                Flags::WITH_SELINUX |
+                Flags::WITH_FCAPS |
+                Flags::WITH_QUOTA_PROJID
+            },
+            XFS_SUPER_MAGIC => {
+                Flags::WITH_2SEC_TIME |
+                Flags::WITH_READ_ONLY |
+                Flags::WITH_PERMISSIONS |
+                Flags::WITH_SYMLINKS |
+                Flags::WITH_DEVICE_NODES |
+                Flags::WITH_FIFOS |
+                Flags::WITH_SOCKETS |
+                Flags::WITH_FLAG_APPEND |
+                Flags::WITH_FLAG_NOATIME |
+                Flags::WITH_FLAG_NODUMP |
+                Flags::WITH_FLAG_IMMUTABLE |
+                Flags::WITH_FLAG_SYNC |
+                Flags::WITH_XATTRS |
+                Flags::WITH_ACL |
+                Flags::WITH_SELINUX |
+                Flags::WITH_FCAPS |
+                Flags::WITH_QUOTA_PROJID
+            },
+            ZFS_SUPER_MAGIC => {
+                Flags::WITH_2SEC_TIME |
+                Flags::WITH_READ_ONLY |
+                Flags::WITH_PERMISSIONS |
+                Flags::WITH_SYMLINKS |
+                Flags::WITH_DEVICE_NODES |
+                Flags::WITH_FIFOS |
+                Flags::WITH_SOCKETS |
+                Flags::WITH_FLAG_APPEND |
+                Flags::WITH_FLAG_NOATIME |
+                Flags::WITH_FLAG_NODUMP |
+                Flags::WITH_FLAG_DIRSYNC |
+                Flags::WITH_FLAG_IMMUTABLE |
+                Flags::WITH_FLAG_SYNC |
+                Flags::WITH_XATTRS |
+                Flags::WITH_ACL |
+                Flags::WITH_SELINUX |
+                Flags::WITH_FCAPS |
+                Flags::WITH_QUOTA_PROJID
+            },
+            BTRFS_SUPER_MAGIC => {
+                Flags::WITH_2SEC_TIME |
+                Flags::WITH_READ_ONLY |
+                Flags::WITH_PERMISSIONS |
+                Flags::WITH_SYMLINKS |
+                Flags::WITH_DEVICE_NODES |
+                Flags::WITH_FIFOS |
+                Flags::WITH_SOCKETS |
+                Flags::WITH_FLAG_APPEND |
+                Flags::WITH_FLAG_NOATIME |
+                Flags::WITH_FLAG_COMPR |
+                Flags::WITH_FLAG_NOCOW |
+                Flags::WITH_FLAG_NODUMP |
+                Flags::WITH_FLAG_DIRSYNC |
+                Flags::WITH_FLAG_IMMUTABLE |
+                Flags::WITH_FLAG_SYNC |
+                Flags::WITH_FLAG_NOCOMP |
+                Flags::WITH_XATTRS |
+                Flags::WITH_ACL |
+                Flags::WITH_SELINUX |
+                Flags::WITH_SUBVOLUME |
+                Flags::WITH_SUBVOLUME_RO |
+                Flags::WITH_FCAPS
+            },
+            TMPFS_MAGIC => {
+                Flags::WITH_2SEC_TIME |
+                Flags::WITH_READ_ONLY |
+                Flags::WITH_PERMISSIONS |
+                Flags::WITH_SYMLINKS |
+                Flags::WITH_DEVICE_NODES |
+                Flags::WITH_FIFOS |
+                Flags::WITH_SOCKETS |
+                Flags::WITH_ACL |
+                Flags::WITH_SELINUX
+            },
+            // FUSE mounts are special as the supported feature set
+            // is not clear a priori.
+            FUSE_SUPER_MAGIC => {
+                Flags::WITH_FUSE
+            },
+            _ => {
+                Flags::WITH_2SEC_TIME |
+                Flags::WITH_READ_ONLY |
+                Flags::WITH_PERMISSIONS |
+                Flags::WITH_SYMLINKS |
+                Flags::WITH_DEVICE_NODES |
+                Flags::WITH_FIFOS |
+                Flags::WITH_SOCKETS
+            },
+        }
     }
 }
index e611ba2632942db6bd4e280015e84df8caecedd1..24bdcd97b0b64ae89a71d8d7496d1863e93449f6 100644 (file)
@@ -14,7 +14,7 @@ use proxmox::sys::error::SysError;
 use proxmox::tools::fd::RawFdNum;
 use proxmox::{c_result, c_try};
 
-use crate::pxar::flags;
+use crate::pxar::Flags;
 use crate::pxar::tools::perms_from_metadata;
 use crate::tools::{acl, fs, xattr};
 
@@ -22,10 +22,6 @@ use crate::tools::{acl, fs, xattr};
 // utility functions
 //
 
-fn flags_contain(flags: u64, test_flag: u64) -> bool {
-    0 != (flags & test_flag)
-}
-
 fn allow_notsupp<E: SysError>(err: E) -> Result<(), E> {
     if err.is_errno(Errno::EOPNOTSUPP) {
         Ok(())
@@ -70,7 +66,7 @@ fn nsec_to_update_timespec(mtime_nsec: u64) -> [libc::timespec; 2] {
 //
 
 pub fn apply_at(
-    flags: u64,
+    flags: Flags,
     metadata: &Metadata,
     parent: RawFd,
     file_name: &CStr,
@@ -86,7 +82,7 @@ pub fn apply_at(
 }
 
 pub fn apply_with_path<T: AsRef<Path>>(
-    flags: u64,
+    flags: Flags,
     metadata: &Metadata,
     fd: RawFd,
     file_name: T,
@@ -99,7 +95,7 @@ pub fn apply_with_path<T: AsRef<Path>>(
     )
 }
 
-pub fn apply(flags: u64, metadata: &Metadata, fd: RawFd, file_name: &CStr) -> Result<(), Error> {
+pub fn apply(flags: Flags, metadata: &Metadata, fd: RawFd, file_name: &CStr) -> Result<(), Error> {
     let c_proc_path = CString::new(format!("/proc/self/fd/{}", fd)).unwrap();
     let c_proc_path = c_proc_path.as_ptr();
 
@@ -156,12 +152,12 @@ pub fn apply(flags: u64, metadata: &Metadata, fd: RawFd, file_name: &CStr) -> Re
 }
 
 fn add_fcaps(
-    flags: u64,
+    flags: Flags,
     c_proc_path: *const libc::c_char,
     metadata: &Metadata,
     skip_xattrs: &mut bool,
 ) -> Result<(), Error> {
-    if *skip_xattrs || !flags_contain(flags, flags::WITH_FCAPS) {
+    if *skip_xattrs || !flags.contains(Flags::WITH_FCAPS) {
         return Ok(());
     }
     let fcaps = match metadata.fcaps.as_ref() {
@@ -185,12 +181,12 @@ fn add_fcaps(
 }
 
 fn apply_xattrs(
-    flags: u64,
+    flags: Flags,
     c_proc_path: *const libc::c_char,
     metadata: &Metadata,
     skip_xattrs: &mut bool,
 ) -> Result<(), Error> {
-    if *skip_xattrs || !flags_contain(flags, flags::WITH_XATTRS) {
+    if *skip_xattrs || !flags.contains(Flags::WITH_XATTRS) {
         return Ok(());
     }
 
@@ -221,11 +217,11 @@ fn apply_xattrs(
 }
 
 fn apply_acls(
-    flags: u64,
+    flags: Flags,
     c_proc_path: *const libc::c_char,
     metadata: &Metadata,
 ) -> Result<(), Error> {
-    if !flags_contain(flags, flags::WITH_ACL) || metadata.acl.is_empty() {
+    if !flags.contains(Flags::WITH_ACL) || metadata.acl.is_empty() {
         return Ok(());
     }
 
@@ -309,8 +305,8 @@ fn apply_acls(
     Ok(())
 }
 
-fn apply_quota_project_id(flags: u64, fd: RawFd, metadata: &Metadata) -> Result<(), Error> {
-    if !flags_contain(flags, flags::WITH_QUOTA_PROJID) {
+fn apply_quota_project_id(flags: Flags, fd: RawFd, metadata: &Metadata) -> Result<(), Error> {
+    if !flags.contains(Flags::WITH_QUOTA_PROJID) {
         return Ok(());
     }
 
index 571d6c21af7e8d9594064a1d0358a5e9f327b132..6e9106670ad72c84b5998f2635d32c19092c8b96 100644 (file)
@@ -52,10 +52,12 @@ pub(crate) mod create;
 pub(crate) mod dir_stack;
 pub(crate) mod extract;
 pub(crate) mod metadata;
-pub mod flags;
 pub mod fuse;
 pub(crate) mod tools;
 
+mod flags;
+pub use flags::Flags;
+
 pub use create::create_archive;
 pub use extract::extract_archive;
 
index e5b2c4cb9f52c68abf8331152cb39efb8aeaf471..a6acf9afb1b93fcd4169395a5d4891644c9765c8 100644 (file)
@@ -29,7 +29,7 @@ fn run_test(dir_name: &str) -> Result<(), Error> {
         dir,
         writer,
         Vec::new(),
-        flags::DEFAULT,
+        Flags::DEFAULT,
         None,
         false,
         |_| Ok(()),