libfs/
lib.rs

1/*
2 * Copyright © 2018, Steve Smith <tarkasteve@gmail.com>
3 *
4 * This program is free software: you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License version
6 * 3 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
15 */
16
17mod common;
18mod errors;
19
20use std::{fs, ops::Range};
21
22use cfg_if::cfg_if;
23use rustix::fs::FileTypeExt;
24
25cfg_if! {
26    if #[cfg(all(target_os = "linux", feature = "use_linux"))] {
27        mod linux;
28        use linux as backend;
29    } else {
30        mod fallback;
31        use fallback as backend;
32    }
33}
34pub use backend::{
35    copy_file_bytes,
36    copy_file_offset,
37    copy_node,
38    copy_sparse,
39    probably_sparse,
40    next_sparse_segments,
41    map_extents,
42    reflink,
43};
44pub use common::{
45    allocate_file,
46    copy_file,
47    copy_owner,
48    copy_permissions,
49    copy_timestamps,
50    is_same_file,
51    merge_extents,
52    sync,
53};
54pub use errors::Error;
55
56/// Flag whether the current OS support
57/// [xattrs](https://man7.org/linux/man-pages/man7/xattr.7.html).
58pub const XATTR_SUPPORTED: bool = {
59    // NOTE: The xattr crate has a SUPPORTED_PLATFORM flag, however it
60    // allows NetBSD, which fails for us, so we stick to platforms we've
61    // tested.
62    cfg_if! {
63        if #[cfg(any(target_os = "linux", target_os = "freebsd"))] {
64            true
65        } else {
66            false
67        }
68    }
69};
70
71/// Enum mapping for various *nix file types. Mapped from
72/// [std::fs::FileType] and [rustix::fs::FileTypeExt].
73#[derive(Debug)]
74pub enum FileType {
75    File,
76    Dir,
77    Symlink,
78    Socket,
79    Fifo,
80    Char,
81    Block,
82    Other
83}
84
85impl From<fs::FileType> for FileType {
86    fn from(ft: fs::FileType) -> Self {
87        if ft.is_dir() {
88            FileType::Dir
89        } else if ft.is_file() {
90            FileType::File
91        } else if ft.is_symlink() {
92            FileType::Symlink
93        } else if ft.is_socket() {
94            FileType::Socket
95        } else if ft.is_fifo() {
96            FileType::Fifo
97        } else if ft.is_char_device() {
98            FileType::Char
99        } else if ft.is_block_device() {
100            FileType::Block
101        } else {
102            FileType::Other
103        }
104    }
105}
106
107/// Struct representing a file extent metadata.
108#[derive(Debug, PartialEq)]
109pub struct Extent {
110    /// Extent logical start
111    pub start: u64,
112    /// Extent logical end
113    pub end: u64,
114    /// Whether extent is shared between multiple file. This generally
115    /// only applies to reflinked files on filesystems that support
116    /// CoW.
117    pub shared: bool,
118}
119
120impl From<Extent> for Range<u64> {
121    fn from(e: Extent) -> Self {
122        e.start..e.end
123    }
124}