From ea0e868c4881944207e9b3a77011e05a505ff3b7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 24 Oct 2017 13:48:15 -0700 Subject: QFileSystemEngine: Fix renameat2() failures on non-local filesystems The RENAME_NOREPLACE flag is supported for all Linux local filesystems, since that can be easily checked by the VFS layer (it knows which files exist and which ones don't). For non-local filesystems, the backend needs support and that might need server-side support too. So we may get EINVAL errors for those, in which case we fall back to link/unlink, which in turn can fall back to rename(). EINVAL can also happen if we attempt to make a directory a subdirectory of itself. In that case, we will attempt to link() it, which will result in EPERM as we can't hardlink directories. Then we try rename() again, which should result in the expected EINVAL. Task-number: QTBUG-64008 Change-Id: Icaa86fc7b54d4b368c0efffd14f09ca23602dd2e Reviewed-by: Oswald Buddenhagen Reviewed-by: Edward Welbourne --- src/corelib/io/qfilesystemengine_unix.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 52512c5e13..d77cdc123c 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -1261,7 +1261,8 @@ bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSy // If we're using syscall(), check for ENOSYS; // if renameat2 came from libc, we don't accept ENOSYS. - if (QT_CONFIG(renameat2) || errno != ENOSYS) { + // We can also get EINVAL for some non-local filesystems. + if ((QT_CONFIG(renameat2) || errno != ENOSYS) && errno != EINVAL) { error = QSystemError(errno, QSystemError::StandardLibraryError); return false; } -- cgit v1.2.3