From: Kevin Ottens Date: Thu, 24 Aug 2023 16:42:19 +0000 (+0200) Subject: [PATCH] Don't unlink + rename on CIFS mounts during copy operations X-Git-Tag: archive/raspbian/5.103.0-1+rpi1+deb12u1^2~3 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=2ded74de12d4f0748c4eb0a6988197366da98f12;p=kio.git [PATCH] Don't unlink + rename on CIFS mounts during copy operations It turns out that the behavior of unlink() on CIFS mounts can be a bit "interesting". If the file one tries to unlink is opened then the operation is claimed to have succeeded but the filename is still visible in the file hierarchy until the last handle is closed. Since we rightfully attempt to copy under a temporary name + unlink + rename during copy() operations this would end badly (as the unlink() would "succeed" but the rename() would fail!). For instance Okular would constantly hit this case but it's likely not the only one to be affected. So instead we detect if the destination is a CIFS mount, in such cases we now overwrite the file directly since this actually succeed. BUG: 454693 (cherry picked from commit d248949eea3e3dcbb9283f30eebcb9ae86412cd1) Gbp-Pq: Name upstream_3e6800b3_fix_cifs_copy.patch --- diff --git a/src/ioslaves/file/file_unix.cpp b/src/ioslaves/file/file_unix.cpp index 1865b85..58017c2 100644 --- a/src/ioslaves/file/file_unix.cpp +++ b/src/ioslaves/file/file_unix.cpp @@ -325,6 +325,12 @@ inline static time_t stat_mtime(const QT_STATBUF &buf) } #endif +static bool isOnCifsMount(const QString &filePath) +{ + const auto mount = KMountPoint::currentMountPoints().findByPath(filePath); + return mount->mountType() == QStringLiteral("cifs") || mount->mountType() == QStringLiteral("smb3"); +} + static bool createUDSEntry(const QString &filename, const QByteArray &path, UDSEntry &entry, KIO::StatDetails details, const QString &fullPath) { assert(entry.count() == 0); // by contract :-) @@ -734,7 +740,7 @@ void FileProtocol::copy(const QUrl &srcUrl, const QUrl &destUrl, int _mode, JobF return; } } - } else if (S_ISREG(buffDest.st_mode)) { + } else if (S_ISREG(buffDest.st_mode) && !isOnCifsMount(dest)) { _destBackup = _dest; dest.append(QStringLiteral(".part")); _dest = QFile::encodeName(dest);