@@ -890,8 +890,11 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
890890 )
891891 } ;
892892 if let Err ( ref copy_err) = copy_result {
893- if let Some ( libc:: ENOSYS ) = copy_err. raw_os_error ( ) {
894- HAS_COPY_FILE_RANGE . store ( false , Ordering :: Relaxed ) ;
893+ match copy_err. raw_os_error ( ) {
894+ Some ( libc:: ENOSYS ) | Some ( libc:: EPERM ) => {
895+ HAS_COPY_FILE_RANGE . store ( false , Ordering :: Relaxed ) ;
896+ }
897+ _ => { }
895898 }
896899 }
897900 copy_result
@@ -902,9 +905,13 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
902905 Ok ( ret) => written += ret as u64 ,
903906 Err ( err) => {
904907 match err. raw_os_error ( ) {
905- Some ( os_err) if os_err == libc:: ENOSYS || os_err == libc:: EXDEV => {
906- // Either kernel is too old or the files are not mounted on the same fs.
907- // Try again with fallback method
908+ Some ( os_err) if os_err == libc:: ENOSYS
909+ || os_err == libc:: EXDEV
910+ || os_err == libc:: EPERM => {
911+ // Try fallback io::copy if either:
912+ // - Kernel version is < 4.5 (ENOSYS)
913+ // - Files are mounted on different fs (EXDEV)
914+ // - copy_file_range is disallowed, for example by seccomp (EPERM)
908915 assert_eq ! ( written, 0 ) ;
909916 let ret = io:: copy ( & mut reader, & mut writer) ?;
910917 writer. set_permissions ( perm) ?;
0 commit comments