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}