56
56
#include "cpdup.h"
57
57
#include "hclink.h"
58
58
#include "hcproto.h"
59
+ #if defined(__FreeBSD__ )
60
+ #include <sys/param.h>
61
+ #endif
59
62
60
63
#define HSIZE 8192
61
64
#define HMASK (HSIZE-1)
@@ -177,6 +180,14 @@ int64_t CountLinkedItems;
177
180
static struct HostConf SrcHost ;
178
181
static struct HostConf DstHost ;
179
182
183
+ #if defined(USE_COPY_FILE_RANGE ) || (defined(__FreeBSD__ ) && __FreeBSD_version > 1300037 )
184
+ static inline int
185
+ chk_ENOTSUP (int err )
186
+ {
187
+ return err == EOPNOTSUPP || (ENOTSUP != EOPNOTSUPP && err == ENOTSUP );
188
+ }
189
+ #endif
190
+
180
191
int
181
192
main (int ac , char * * av )
182
193
{
@@ -1131,7 +1142,38 @@ DoCopy(copy_info_t info, struct stat *stat1, int depth)
1131
1142
const char * op ;
1132
1143
char * iobuf1 = malloc (GETIOSIZE );
1133
1144
int n ;
1145
+ #if defined(USE_COPY_FILE_RANGE ) || (defined(__FreeBSD__ ) && __FreeBSD_version > 1300037 )
1146
+ int do_std_copy = 0 ;
1134
1147
1148
+ /*
1149
+ * For local file transfers try copy_file_range(2)
1150
+ */
1151
+ if (SrcHost .host == NULL && DstHost .host == NULL ) {
1152
+ ssize_t wcnt ;
1153
+ do {
1154
+ wcnt = copy_file_range (fd1 , NULL , fd2 , NULL ,
1155
+ SSIZE_MAX , 0 );
1156
+ } while (wcnt > 0 );
1157
+ if (wcnt < 0 ) {
1158
+ /*
1159
+ * On selected errnos we retry with standard copy
1160
+ */
1161
+ if (errno == EINVAL || errno == EBADF ||
1162
+ errno == ENOSYS || errno == EXDEV ||
1163
+ errno == ETXTBSY || chk_ENOTSUP (errno ))
1164
+ do_std_copy = 1 ;
1165
+ else
1166
+ n = -1 ;
1167
+ } else
1168
+ n = 0 ;
1169
+ } else
1170
+ do_std_copy = 1 ;
1171
+
1172
+ /*
1173
+ * Do standard copy if remote or copy_file_range(2) has failed
1174
+ */
1175
+ if (do_std_copy ) {
1176
+ #endif
1135
1177
/*
1136
1178
* Matt: What about holes?
1137
1179
*/
@@ -1142,6 +1184,9 @@ DoCopy(copy_info_t info, struct stat *stat1, int depth)
1142
1184
break ;
1143
1185
op = "read" ;
1144
1186
}
1187
+ #if defined(USE_COPY_FILE_RANGE ) || (defined(__FreeBSD__ ) && __FreeBSD_version > 1300037 )
1188
+ }
1189
+ #endif
1145
1190
hc_close (& DstHost , fd2 );
1146
1191
if (n == 0 ) {
1147
1192
struct timeval tv [2 ];
0 commit comments