@@ -72,7 +72,8 @@ impl LinkMode {
72
72
/// via copy-on-write, which is similar to a hard link, but allows the files to be modified
73
73
/// independently (that is, the file is copied upon modification).
74
74
///
75
- /// This method uses `clonefile` on macOS, and `reflink` on Linux.
75
+ /// This method uses `clonefile` on macOS, and `reflink` on Linux. See [`clone_recursive`] for
76
+ /// details.
76
77
fn clone_wheel_files (
77
78
site_packages : impl AsRef < Path > ,
78
79
wheel : impl AsRef < Path > ,
@@ -81,17 +82,6 @@ fn clone_wheel_files(
81
82
let mut count = 0usize ;
82
83
let mut attempt = Attempt :: default ( ) ;
83
84
84
- // On macOS, directories can be recursively copied with a single `clonefile` call.
85
- // So we only need to iterate over the top-level of the directory, and copy each file or
86
- // subdirectory unless the subdirectory exists already in which case we'll need to recursively
87
- // merge its contents with the existing directory.
88
- //
89
- // On linux, we need to always reflink recursively, as `FICLONE` ioctl does not support directories.
90
- // Also note, that reflink is only supported on certain filesystems (btrfs, xfs, ...), and only when
91
- // it does not cross filesystem boundaries.
92
- //
93
- // On windows, we also always need to reflink recursively, as `FSCTL_DUPLICATE_EXTENTS_TO_FILE` ioctl
94
- // is not supported on directories. Also, it is only supported on certain filesystems (ReFS, SMB, ...).
95
85
for entry in fs:: read_dir ( wheel. as_ref ( ) ) ? {
96
86
clone_recursive (
97
87
site_packages. as_ref ( ) ,
@@ -144,6 +134,21 @@ enum Attempt {
144
134
}
145
135
146
136
/// Recursively clone the contents of `from` into `to`.
137
+ ///
138
+ /// Note the behavior here is platform-dependent.
139
+ ///
140
+ /// On macOS, directories can be recursively copied with a single `clonefile` call. So we only
141
+ /// need to iterate over the top-level of the directory, and copy each file or subdirectory
142
+ /// unless the subdirectory exists already in which case we'll need to recursively merge its
143
+ /// contents with the existing directory.
144
+ ///
145
+ /// On Linux, we need to always reflink recursively, as `FICLONE` ioctl does not support
146
+ /// directories. Also note, that reflink is only supported on certain filesystems (btrfs, xfs,
147
+ /// ...), and only when it does not cross filesystem boundaries.
148
+ ///
149
+ /// On Windows, we also always need to reflink recursively, as `FSCTL_DUPLICATE_EXTENTS_TO_FILE`
150
+ /// ioctl is not supported on directories. Also, it is only supported on certain filesystems
151
+ /// (ReFS, SMB, ...).
147
152
fn clone_recursive (
148
153
site_packages : & Path ,
149
154
wheel : & Path ,
@@ -158,7 +163,6 @@ fn clone_recursive(
158
163
trace ! ( "Cloning {} to {}" , from. display( ) , to. display( ) ) ;
159
164
160
165
if ( cfg ! ( windows) || cfg ! ( target_os = "linux" ) ) && from. is_dir ( ) {
161
- // On Windows, reflinking directories is not supported, so we copy each file instead.
162
166
fs:: create_dir_all ( & to) ?;
163
167
for entry in fs:: read_dir ( from) ? {
164
168
clone_recursive ( site_packages, wheel, locks, & entry?, attempt) ?;
@@ -170,7 +174,8 @@ fn clone_recursive(
170
174
Attempt :: Initial => {
171
175
if let Err ( err) = reflink:: reflink ( & from, & to) {
172
176
if err. kind ( ) == std:: io:: ErrorKind :: AlreadyExists {
173
- // If cloning/copying fails and the directory exists already, it must be merged recursively.
177
+ // If cloning or copying fails and the directory exists already, it must be
178
+ // merged recursively.
174
179
if entry. file_type ( ) ?. is_dir ( ) {
175
180
for entry in fs:: read_dir ( from) ? {
176
181
clone_recursive ( site_packages, wheel, locks, & entry?, attempt) ?;
@@ -197,7 +202,7 @@ fn clone_recursive(
197
202
from. display( ) ,
198
203
to. display( )
199
204
) ;
200
- // switch to copy fallback
205
+ // Fallback to copying
201
206
* attempt = Attempt :: UseCopyFallback ;
202
207
clone_recursive ( site_packages, wheel, locks, entry, attempt) ?;
203
208
}
0 commit comments