From fe75526542dd77afb3f8d0d32ad5f7d22b6c5fbb Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 21 Jan 2025 10:46:27 -0800 Subject: [PATCH] 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 --- src/corelib/io/qfilesystemengine_unix.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 15a004df13b..a040a60de29 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -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; }