1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//! Some file systems implement COW (copy on write) functionality in order to speed up file copies.
//! On a high level, the new file does not actually get copied, but shares the same on-disk data
//! with the source file. As soon as one of the files is modified, the actual copying is done by
//! the underlying OS.
//!
//! This library exposes a single function, `reflink`, which attempts to copy a file using the
//! underlying OSs' block cloning capabilities. The function signature is identical to `std::fs::copy`.
//!
//! At the moment Linux, Android, OSX, ios and Windows are supported.
//! As soon as other OS support the functionality, support will be added.
use fs;
use io;
use Path;
/// Copies a file using COW semantics.
///
/// For compatibility reasons with macos, the target file will be created using `OpenOptions::create_new`.
/// If you want to overwrite existing files, make sure you manually delete the target file first
/// if it exists.
///
/// ```rust
/// use reflink;
/// match reflink::reflink("src.txt", "dest.txt") {
/// Ok(()) => println!("file has been reflinked"),
/// Err(e) => println!("error while reflinking: {:?}", e)
/// }
/// ```
/// # Implementation details per platform
/// ## Linux / Android
/// Uses `ioctl_ficlone`. Supported file systems include btrfs and XFS (and maybe more in the future).
/// ## OS X / ios
/// Uses `clonefile` library function. This is supported on OS X Version >=10.12 and iOS version >= 10.0
/// This will work on APFS partitions (which means most desktop systems are capable).
/// ## Windows
/// Uses ioctl `FSCTL_DUPLICATE_EXTENTS_TO_FILE`.
/// Only supports ReFS on Windows Server. *Important note*: The windows implementation is currently
/// untested and probably buggy. Contributions/testers with access to a Windows Server welcome.
/// Attempts to reflink a file. If the operation fails, a conventional copy operation is
/// attempted as a fallback.
///
/// If the function reflinked a file, the return value will be `Ok(None)``.
///
/// If the function copied a file, the return value will be `Ok(Some(written))`.
///
/// ```rust
/// use reflink;
/// match reflink::reflink_or_copy("src.txt", "dest.txt") {
/// Ok(None) => println!("file has been reflinked"),
/// Ok(Some(written)) => println!("file has been copied ({} bytes)", written),
/// Err(e) => println!("an error occured: {:?}", e)
/// }
/// ```