QFileSystemEngine/Linux: detect sendfile() permanent errors

sendfile(2) isn't always able to send to all file types, so current code
only detected the ability to send by having sent something. This commit
tries a little harder to detect permanent data-send problems on the
first try. I'm unable to find a case where this fails on Linux, in
particular because we don't enter this block if the source file isn't
S_IFREG.

Now, on Linux, there's no file-copy pump:
openat(AT_FDCWD, "dummy.o", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/tmp/tmp", O_RDWR|O_CLOEXEC|O_TMPFILE, 0600) = 5
ioctl(5, BTRFS_IOC_CLONE or FICLONE, 4) = -1 EXDEV
sendfile(5, 4, NULL, 2147479552)        = -1 ENOSPC
lseek(5, 0, SEEK_SET)                   = 0
close(5)                                = 0
write(2, "\"Could not copy to /tmp/tmp/f: No space left on device\"") = 56
close(4)                                = 0

Change-Id: I88ce23447b0d7341848cfffd2c469e15cb69f5a6
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
This commit is contained in:
Thiago Macieira 2025-01-21 10:46:27 -08:00
parent be2df3c6e0
commit fe75526542

View File

@ -1103,6 +1103,12 @@ auto QFileSystemEngine::cloneFile(int srcfd, int dstfd, const QFileSystemMetaDat
ssize_t n = ::sendfile(dstfd, srcfd, nullptr, SendfileSize);
if (n == -1) {
switch (errno) {
case ENOSPC:
case EIO:
return TriStateResult::Failed;
}
// if we got an error here, give up and try at an upper layer
return TriStateResult::NotSupported;
}