From d5b6d93978a772185a9c122fb391be1fa0e7ec84 Mon Sep 17 00:00:00 2001 From: allexzander Date: Wed, 31 Mar 2021 14:47:34 +0300 Subject: [PATCH 1/8] Fix VFS freeze when syncing '.lnk' files on Windows. Signed-off-by: allexzander --- src/libsync/discovery.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index edded199a7373..7d12a8acddb3b 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -501,12 +501,22 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo( }); return; } +#ifdef Q_OS_WIN + const bool forceAlwaysLocal = item->_type == ItemTypeFile && item->_fileId.endsWith(".lnk"); +#else + const bool forceAlwaysLocal = false; +#endif + if (forceAlwaysLocal) { + int a = 5; + a = 6; + } // Turn new remote files into virtual files if the option is enabled. auto &opts = _discoveryData->_syncOptions; if (!localEntry.isValid() && item->_type == ItemTypeFile && opts._vfs->mode() != Vfs::Off - && _pinState != PinState::AlwaysLocal) { + && _pinState != PinState::AlwaysLocal + && !forceAlwaysLocal) { item->_type = ItemTypeVirtualFile; if (isVfsWithSuffix()) addVirtualFileSuffix(tmp_path._original); From 7235c708dced0e4c6262e8ac3fae23d9e303b609 Mon Sep 17 00:00:00 2001 From: allexzander Date: Wed, 31 Mar 2021 16:36:13 +0300 Subject: [PATCH 2/8] Added .lnk file placeholder creation fix. Signed-off-by: allexzander --- src/libsync/discovery.cpp | 17 +++++++---------- src/libsync/syncengine.cpp | 6 +++++- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index 7d12a8acddb3b..47b4f2cf5517d 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -14,6 +14,9 @@ #include "discovery.h" #include "common/syncjournaldb.h" +#ifdef Q_OS_WIN +#include "common/filesystembase.h" +#endif #include "syncfileitem.h" #include #include @@ -501,22 +504,16 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo( }); return; } -#ifdef Q_OS_WIN - const bool forceAlwaysLocal = item->_type == ItemTypeFile && item->_fileId.endsWith(".lnk"); -#else - const bool forceAlwaysLocal = false; -#endif - if (forceAlwaysLocal) { - int a = 5; - a = 6; - } // Turn new remote files into virtual files if the option is enabled. auto &opts = _discoveryData->_syncOptions; if (!localEntry.isValid() && item->_type == ItemTypeFile && opts._vfs->mode() != Vfs::Off && _pinState != PinState::AlwaysLocal - && !forceAlwaysLocal) { +#ifdef Q_OS_WIN + && !FileSystem::isLnkFile(path._server) +#endif + ) { item->_type = ItemTypeVirtualFile; if (isVfsWithSuffix()) addVirtualFileSuffix(tmp_path._original); diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index f6a23261a2a48..086da5cac056e 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -345,7 +345,11 @@ void OCC::SyncEngine::slotItemDiscovered(const OCC::SyncFileItemPtr &item) rec._serverHasIgnoredFiles |= prev._serverHasIgnoredFiles; // Ensure it's a placeholder file on disk - if (item->_type == ItemTypeFile) { + if (item->_type == ItemTypeFile +#ifdef Q_OS_WIN + && !FileSystem::isLnkFile(filePath) +#endif + ) { const auto result = _syncOptions._vfs->convertToPlaceholder(filePath, *item); if (!result) { item->_instruction = CSYNC_INSTRUCTION_ERROR; From 3906ae09228af393f08cfea6a05b516f7880eaaa Mon Sep 17 00:00:00 2001 From: allexzander Date: Wed, 31 Mar 2021 17:19:01 +0300 Subject: [PATCH 3/8] Another way to fix this. Signed-off-by: allexzander --- src/libsync/discovery.cpp | 8 +++++--- src/libsync/syncengine.cpp | 6 +----- src/libsync/vfs/cfapi/vfs_cfapi.cpp | 4 +++- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index 47b4f2cf5517d..a24cb4d68184b 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -510,11 +510,13 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo( && item->_type == ItemTypeFile && opts._vfs->mode() != Vfs::Off && _pinState != PinState::AlwaysLocal -#ifdef Q_OS_WIN - && !FileSystem::isLnkFile(path._server) -#endif ) { item->_type = ItemTypeVirtualFile; +#ifdef Q_OS_WIN + if(FileSystem::isLnkFile(path._server)) { + item->_type = ItemTypeVirtualFileDownload; + } +#endif if (isVfsWithSuffix()) addVirtualFileSuffix(tmp_path._original); } diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index 086da5cac056e..f6a23261a2a48 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -345,11 +345,7 @@ void OCC::SyncEngine::slotItemDiscovered(const OCC::SyncFileItemPtr &item) rec._serverHasIgnoredFiles |= prev._serverHasIgnoredFiles; // Ensure it's a placeholder file on disk - if (item->_type == ItemTypeFile -#ifdef Q_OS_WIN - && !FileSystem::isLnkFile(filePath) -#endif - ) { + if (item->_type == ItemTypeFile) { const auto result = _syncOptions._vfs->convertToPlaceholder(filePath, *item); if (!result) { item->_instruction = CSYNC_INSTRUCTION_ERROR; diff --git a/src/libsync/vfs/cfapi/vfs_cfapi.cpp b/src/libsync/vfs/cfapi/vfs_cfapi.cpp index c9d05ce07e174..b5b2cb9e2dc49 100644 --- a/src/libsync/vfs/cfapi/vfs_cfapi.cpp +++ b/src/libsync/vfs/cfapi/vfs_cfapi.cpp @@ -196,7 +196,9 @@ bool VfsCfApi::statTypeVirtualFile(csync_file_stat_t *stat, void *statData) stat->type = ItemTypeVirtualFileDownload; return true; } else if (!isSparseFile && isUnpinned){ - stat->type = ItemTypeVirtualFileDehydration; + if (!FileSystem::isLnkFile(stat->path)) { + stat->type = ItemTypeVirtualFileDehydration; + } return true; } else if (isSparseFile) { stat->type = ItemTypeVirtualFile; From 13f4bb541d0a675daf347c352cf758ef8a8db0c6 Mon Sep 17 00:00:00 2001 From: allexzander Date: Thu, 1 Apr 2021 16:09:26 +0300 Subject: [PATCH 4/8] Treat .lnk files as normal files without hydrating them or creating a placeholder. Signed-off-by: allexzander --- src/libsync/discovery.cpp | 10 +++++----- src/libsync/vfs/cfapi/vfs_cfapi.cpp | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index a24cb4d68184b..9c3f2d9d003ac 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -510,13 +510,13 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo( && item->_type == ItemTypeFile && opts._vfs->mode() != Vfs::Off && _pinState != PinState::AlwaysLocal - ) { - item->_type = ItemTypeVirtualFile; #ifdef Q_OS_WIN - if(FileSystem::isLnkFile(path._server)) { - item->_type = ItemTypeVirtualFileDownload; - } + // on Windows, ".lnk" files are causing troubles with QFileInfo - always treat them as normal files + && !FileSystem::isLnkFile(path._server) #endif + ) { + item->_type = ItemTypeVirtualFile; + if (isVfsWithSuffix()) addVirtualFileSuffix(tmp_path._original); } diff --git a/src/libsync/vfs/cfapi/vfs_cfapi.cpp b/src/libsync/vfs/cfapi/vfs_cfapi.cpp index b5b2cb9e2dc49..d8b96cb41594b 100644 --- a/src/libsync/vfs/cfapi/vfs_cfapi.cpp +++ b/src/libsync/vfs/cfapi/vfs_cfapi.cpp @@ -197,9 +197,9 @@ bool VfsCfApi::statTypeVirtualFile(csync_file_stat_t *stat, void *statData) return true; } else if (!isSparseFile && isUnpinned){ if (!FileSystem::isLnkFile(stat->path)) { - stat->type = ItemTypeVirtualFileDehydration; + stat->type = ItemTypeVirtualFileDehydration; + return true; } - return true; } else if (isSparseFile) { stat->type = ItemTypeVirtualFile; return true; From cb8b6ccd9b55f81ed2861d47d397b3b9e599fd00 Mon Sep 17 00:00:00 2001 From: allexzander Date: Thu, 1 Apr 2021 17:54:45 +0300 Subject: [PATCH 5/8] Ignore *.lnk files on Windows. Signed-off-by: allexzander --- src/libsync/discovery.cpp | 16 ++++++++-------- src/libsync/discoveryphase.cpp | 11 ++++++++++- src/libsync/vfs/cfapi/vfs_cfapi.cpp | 10 +++++----- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index 9c3f2d9d003ac..636e64c9de0fc 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -180,9 +180,15 @@ void ProcessDirectoryJob::process() // local stat function. // Recall file shall not be ignored (#4420) bool isHidden = e.localEntry.isHidden || (f.first[0] == '.' && f.first != QLatin1String(".sys.admin#recall#")); +#ifdef Q_OS_WIN + // exclude ".lnk" files as they are not essential, but, causing troubles when enabling the VFS due to QFileInfo::isDir() and other methods are freezing, which causes the ".lnk" files to start hydrating and freezing the app eventually. + const bool isServerEntrySymLink = !e.localEntry.isValid() && e.serverEntry.isValid() && !e.serverEntry.isDirectory && FileSystem::isLnkFile(e.serverEntry.name); +#else + const bool isServerEntrySymLink = false; +#endif if (handleExcluded(path._target, e.localEntry.name, e.localEntry.isDirectory || e.serverEntry.isDirectory, isHidden, - e.localEntry.isSymLink)) + e.localEntry.isSymLink || isServerEntrySymLink)) continue; if (_queryServer == InBlackList || _discoveryData->isInSelectiveSyncBlackList(path._original)) { @@ -509,14 +515,8 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo( if (!localEntry.isValid() && item->_type == ItemTypeFile && opts._vfs->mode() != Vfs::Off - && _pinState != PinState::AlwaysLocal -#ifdef Q_OS_WIN - // on Windows, ".lnk" files are causing troubles with QFileInfo - always treat them as normal files - && !FileSystem::isLnkFile(path._server) -#endif - ) { + && _pinState != PinState::AlwaysLocal) { item->_type = ItemTypeVirtualFile; - if (isVfsWithSuffix()) addVirtualFileSuffix(tmp_path._original); } diff --git a/src/libsync/discoveryphase.cpp b/src/libsync/discoveryphase.cpp index c8b522dcfcea6..5cb1c7c55be58 100644 --- a/src/libsync/discoveryphase.cpp +++ b/src/libsync/discoveryphase.cpp @@ -20,6 +20,9 @@ #include "common/asserts.h" #include "common/checksums.h" +#ifdef Q_OS_WIN +#include "common/filesystembase.h" +#endif #include #include "vio/csync_vio_local.h" @@ -305,7 +308,13 @@ void DiscoverySingleLocalDirectoryJob::run() { i.inode = dirent->inode; i.isDirectory = dirent->type == ItemTypeDirectory; i.isHidden = dirent->is_hidden; - i.isSymLink = dirent->type == ItemTypeSoftLink; +#ifdef Q_OS_WIN + // exclude ".lnk" files as they are not essential, but, causing troubles when enabling the VFS due to QFileInfo::isDir() and other methods are freezing, which causes the ".lnk" files to start hydrating and freezing the app eventually. + const bool isWindowsShortcut = dirent->type == ItemTypeFile && FileSystem::isLnkFile(i.name); +#else + const bool isWindowsShortcut = false; +#endif + i.isSymLink = dirent->type == ItemTypeSoftLink || isWindowsShortcut; i.isVirtualFile = dirent->type == ItemTypeVirtualFile || dirent->type == ItemTypeVirtualFileDownload; i.type = dirent->type; results.push_back(i); diff --git a/src/libsync/vfs/cfapi/vfs_cfapi.cpp b/src/libsync/vfs/cfapi/vfs_cfapi.cpp index d8b96cb41594b..dcd75d46d0694 100644 --- a/src/libsync/vfs/cfapi/vfs_cfapi.cpp +++ b/src/libsync/vfs/cfapi/vfs_cfapi.cpp @@ -184,6 +184,8 @@ bool VfsCfApi::statTypeVirtualFile(csync_file_stat_t *stat, void *statData) const auto hasReparsePoint = (ffd->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0; const auto hasCloudTag = (ffd->dwReserved0 & IO_REPARSE_TAG_CLOUD) != 0; + const auto isWindowsShortcut = !isDirectory && FileSystem::isLnkFile(stat->path); + // It's a dir with a reparse point due to the placeholder info (hence the cloud tag) // if we don't remove the reparse point flag the discovery will end up thinking // it is a file... let's prevent it @@ -195,11 +197,9 @@ bool VfsCfApi::statTypeVirtualFile(csync_file_stat_t *stat, void *statData) } else if (isSparseFile && isPinned) { stat->type = ItemTypeVirtualFileDownload; return true; - } else if (!isSparseFile && isUnpinned){ - if (!FileSystem::isLnkFile(stat->path)) { - stat->type = ItemTypeVirtualFileDehydration; - return true; - } + } else if (!isSparseFile && isUnpinned && !isWindowsShortcut){ + stat->type = ItemTypeVirtualFileDehydration; + return true; } else if (isSparseFile) { stat->type = ItemTypeVirtualFile; return true; From de85b79bb864406543b118b37110f51e73ac2c72 Mon Sep 17 00:00:00 2001 From: allexzander Date: Mon, 5 Apr 2021 14:08:20 +0300 Subject: [PATCH 6/8] Address review comments. Signed-off-by: allexzander --- src/libsync/discovery.cpp | 4 +--- src/libsync/discoveryphase.cpp | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index 636e64c9de0fc..c318c85c62b59 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -13,10 +13,8 @@ */ #include "discovery.h" -#include "common/syncjournaldb.h" -#ifdef Q_OS_WIN #include "common/filesystembase.h" -#endif +#include "common/syncjournaldb.h" #include "syncfileitem.h" #include #include diff --git a/src/libsync/discoveryphase.cpp b/src/libsync/discoveryphase.cpp index 5cb1c7c55be58..bce9276ad8bfd 100644 --- a/src/libsync/discoveryphase.cpp +++ b/src/libsync/discoveryphase.cpp @@ -20,9 +20,7 @@ #include "common/asserts.h" #include "common/checksums.h" -#ifdef Q_OS_WIN #include "common/filesystembase.h" -#endif #include #include "vio/csync_vio_local.h" From 82953d0601787ba3557b5d5fb852516d589cec1c Mon Sep 17 00:00:00 2001 From: allexzander Date: Tue, 6 Apr 2021 10:36:35 +0300 Subject: [PATCH 7/8] Fix review comments. Signed-off-by: allexzander --- src/csync/vio/csync_vio_local_win.cpp | 3 ++- src/libsync/discoveryphase.cpp | 9 +-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/csync/vio/csync_vio_local_win.cpp b/src/csync/vio/csync_vio_local_win.cpp index cc31927d566d1..7aa07f4da4eac 100644 --- a/src/csync/vio/csync_vio_local_win.cpp +++ b/src/csync/vio/csync_vio_local_win.cpp @@ -163,7 +163,8 @@ std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *h } else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { file_stat->type = ItemTypeDirectory; } else { - file_stat->type = ItemTypeFile; + // exclude ".lnk" files as they are not essential, but, causing troubles when enabling the VFS due to QFileInfo::isDir() and other methods are freezing, which causes the ".lnk" files to start hydrating and freezing the app eventually. + file_stat->type = !OCC::FileSystem::isLnkFile(path) ? ItemTypeFile : ItemTypeSoftLink; } /* Check for the hidden flag */ diff --git a/src/libsync/discoveryphase.cpp b/src/libsync/discoveryphase.cpp index bce9276ad8bfd..c8b522dcfcea6 100644 --- a/src/libsync/discoveryphase.cpp +++ b/src/libsync/discoveryphase.cpp @@ -20,7 +20,6 @@ #include "common/asserts.h" #include "common/checksums.h" -#include "common/filesystembase.h" #include #include "vio/csync_vio_local.h" @@ -306,13 +305,7 @@ void DiscoverySingleLocalDirectoryJob::run() { i.inode = dirent->inode; i.isDirectory = dirent->type == ItemTypeDirectory; i.isHidden = dirent->is_hidden; -#ifdef Q_OS_WIN - // exclude ".lnk" files as they are not essential, but, causing troubles when enabling the VFS due to QFileInfo::isDir() and other methods are freezing, which causes the ".lnk" files to start hydrating and freezing the app eventually. - const bool isWindowsShortcut = dirent->type == ItemTypeFile && FileSystem::isLnkFile(i.name); -#else - const bool isWindowsShortcut = false; -#endif - i.isSymLink = dirent->type == ItemTypeSoftLink || isWindowsShortcut; + i.isSymLink = dirent->type == ItemTypeSoftLink; i.isVirtualFile = dirent->type == ItemTypeVirtualFile || dirent->type == ItemTypeVirtualFileDownload; i.type = dirent->type; results.push_back(i); From 4b58c2b7b711f87ea0bf96d83d938b91d4ed0e4a Mon Sep 17 00:00:00 2001 From: allexzander Date: Wed, 7 Apr 2021 10:41:59 +0300 Subject: [PATCH 8/8] Fix review comments. Signed-off-by: allexzander --- src/libsync/discovery.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index c318c85c62b59..b83493c2ba539 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -180,13 +180,13 @@ void ProcessDirectoryJob::process() bool isHidden = e.localEntry.isHidden || (f.first[0] == '.' && f.first != QLatin1String(".sys.admin#recall#")); #ifdef Q_OS_WIN // exclude ".lnk" files as they are not essential, but, causing troubles when enabling the VFS due to QFileInfo::isDir() and other methods are freezing, which causes the ".lnk" files to start hydrating and freezing the app eventually. - const bool isServerEntrySymLink = !e.localEntry.isValid() && e.serverEntry.isValid() && !e.serverEntry.isDirectory && FileSystem::isLnkFile(e.serverEntry.name); + const bool isServerEntryWindowsShortcut = !e.localEntry.isValid() && e.serverEntry.isValid() && !e.serverEntry.isDirectory && FileSystem::isLnkFile(e.serverEntry.name); #else - const bool isServerEntrySymLink = false; + const bool isServerEntryWindowsShortcut = false; #endif if (handleExcluded(path._target, e.localEntry.name, e.localEntry.isDirectory || e.serverEntry.isDirectory, isHidden, - e.localEntry.isSymLink || isServerEntrySymLink)) + e.localEntry.isSymLink || isServerEntryWindowsShortcut)) continue; if (_queryServer == InBlackList || _discoveryData->isInSelectiveSyncBlackList(path._original)) {