diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2023-09-20 23:48:49 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2023-10-17 19:08:25 -0700 |
commit | 25b19907842b199037a100abd97f2126f34ea3d6 (patch) | |
tree | 11199fe9b30309ec27aab156db41530e3bd54952 /src/corelib | |
parent | 77c661b275dbc66798b2ac01eadcbb65c6bdaa88 (diff) |
moveToTrash/Unix: use the file's inode number as collision avoidance
Instead of a sequential and thus predictable counter. This improves the
performance of when you keep creating and trashing the same file base
name. The previous algorithm would try all occurrences from 0 to however
many trashings have happened.
This could have been any random number, but the source file's inode is
"random" enough for us.
strace of the second file's trashing:
openat(AT_FDCWD, "/home/tjmaciei/.qttest/share/Trash/info/tst_qfile.moveToTrashOpenFile.vLwfNe.trashinfo", O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC, 0666) = -1 EEXIST (File exists)
newfstatat(AT_FDCWD, "/home/tjmaciei/tst_qfile.moveToTrashOpenFile.vLwfNe", {st_mode=S_IFREG|0644, st_size=16, ...}, 0) = 0
openat(AT_FDCWD, "/home/tjmaciei/.qttest/share/Trash/info/tst_qfile.moveToTrashOpenFile.vLwfNe-23527891.trashinfo", O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC, 0666) = 4
newfstatat(AT_FDCWD, "/etc/localtime", {st_mode=S_IFREG|0644, st_size=2852, ...}, 0) = 0
write(4, "[Trash Info]\nPath=/home/tjmaciei"..., 103) = 103
renameat2(AT_FDCWD, "/home/tjmaciei/tst_qfile.moveToTrashOpenFile.vLwfNe", AT_FDCWD, "/home/tjmaciei/.qttest/share/Trash/files/tst_qfile.moveToTrashOpenFile.vLwfNe-23527891", RENAME_NOREPLACE) = 0
close(4) = 0
Change-Id: I9d43e5b91eb142d6945cfffd1786d73459c2eb3d
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/io/qfilesystemengine_unix.cpp | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 64ada6c83c..75c682d807 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -1418,14 +1418,25 @@ bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &source, */ QString uniqueTrashedName = u'/' + sourcePath.fileName(); if (!op.tryCreateInfoFile(uniqueTrashedName, error) && error.errorCode == EEXIST) { - for (int counter = 0; op.infoFileFd == -1; ++counter) { - uniqueTrashedName = QString::asprintf("/%ls-%04d", qUtf16Printable(sourcePath.fileName()), - counter); + // we'll use a counter, starting with the file's inode number to avoid + // collisions + qulonglong counter; + if (QT_STATBUF st; Q_LIKELY(QT_STAT(source.nativeFilePath(), &st) == 0)) { + counter = st.st_ino; + } else { + error = QSystemError(errno, QSystemError::StandardLibraryError); + return false; + } + + QString uniqueTrashBase = std::move(uniqueTrashedName); + for (;;) { + uniqueTrashedName = QString::asprintf("%ls-%llu", qUtf16Printable(uniqueTrashBase), + counter++); if (op.tryCreateInfoFile(uniqueTrashedName, error)) break; if (error.errorCode != EEXIST) return false; - } + }; } QByteArray info = |