mirror of https://github.com/qt/qtbase.git
QFileSystemEngine/Unix: work around FreeBSD bug in copy_file_range(2)
Amends commit9b006eb91a
, which introduced the use of this function. When I tested this with FreeBSD 14.2, this code worked; now with 14.3 it doesn't, because on output the srcoffset and dstoffset variables are still zero, in spite of having copied content. That caused the copy_file_range() loop to copy the same files over and over again, never exiting. I've tracked this down to a change in 14.3[1] which showed that if both inoffp and outoffp were non-NULL, it wouldn't update. FreeBSD maintainers report this is already fixed[2] and will be made available soon. tst_qfile now passes again on FreeBSD. strace output on Linux: ioctl(5, BTRFS_IOC_CLONE or FICLONE, 4) = -1 EOPNOTSUPP (Operation not supported) copy_file_range(4, [0], 5, NULL, 9223372036854775807, 0) = 13587 copy_file_range(4, [13587], 5, NULL, 9223372036854775807, 0) = 0 truss output on FreeBSD: copy_file_range(0x4,0x32fb9588e360,0x5,0x0,0x7fffffffffffffff,0x0) = 624 (0x270) copy_file_range(0x4,0x32fb9588e360,0x5,0x0,0x7fffffffffffffff,0x0) = 0 (0x0) No changelog because the content is new in 6.10. [1]1d2fd8c9cf
[2]4046ad6bb0
Pick-to: 6.10 Fixes: QTBUG-138570 Change-Id: I31ddcefb63bb738f0cc0fffd75d9f68030952ed5 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
This commit is contained in:
parent
66a0fa62bf
commit
35dbd1c3f4
|
@ -1178,10 +1178,9 @@ auto QFileSystemEngine::cloneFile(int srcfd, int dstfd, const QFileSystemMetaDat
|
||||||
// across mountpoints, Linux currently (6.12) can only if the source and
|
// across mountpoints, Linux currently (6.12) can only if the source and
|
||||||
// destination mountpoints are the same filesystem type.
|
// destination mountpoints are the same filesystem type.
|
||||||
QT_OFF_T srcoffset = 0;
|
QT_OFF_T srcoffset = 0;
|
||||||
QT_OFF_T dstoffset = 0;
|
|
||||||
ssize_t copied;
|
ssize_t copied;
|
||||||
do {
|
do {
|
||||||
copied = ::copy_file_range(srcfd, &srcoffset, dstfd, &dstoffset, SSIZE_MAX, 0);
|
copied = ::copy_file_range(srcfd, &srcoffset, dstfd, nullptr, SSIZE_MAX, 0);
|
||||||
} while (copied > 0 || (copied < 0 && errno == EINTR));
|
} while (copied > 0 || (copied < 0 && errno == EINTR));
|
||||||
if (copied == 0)
|
if (copied == 0)
|
||||||
return TriStateResult::Success; // EOF -> success
|
return TriStateResult::Success; // EOF -> success
|
||||||
|
|
Loading…
Reference in New Issue