diff --git a/src/common/filesystembase.cpp b/src/common/filesystembase.cpp index 765b081bff..8371cc3360 100644 --- a/src/common/filesystembase.cpp +++ b/src/common/filesystembase.cpp @@ -131,6 +131,7 @@ void FileSystem::setFileReadOnly(const QString &filename, bool readonly) { qCWarning(lcFileSystem()) << filename << (readonly ? "readonly" : "read write") << e.what(); } + return; } #endif QFile file(filename); diff --git a/src/gui/tray/activitylistmodel.cpp b/src/gui/tray/activitylistmodel.cpp index f2fc26ba1e..47cc441f6c 100644 --- a/src/gui/tray/activitylistmodel.cpp +++ b/src/gui/tray/activitylistmodel.cpp @@ -275,9 +275,9 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const case DisplayPathRole: return getDisplayPath(); case PathRole: - return QFileInfo(getFilePath()).path(); + return getFilePath(); case OpenablePathRole: - return a._isMultiObjectActivity ? QFileInfo(getFilePath()).canonicalPath() : QFileInfo(getFilePath()).canonicalFilePath(); + return getFilePath(); case DisplayLocationRole: return displayLocation(); case ActionsLinksRole: { diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index 7300a4c5f9..f4a98b5182 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -1193,11 +1193,7 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo( item->_direction = SyncFileItem::Down; item->_instruction = CSYNC_INSTRUCTION_SYNC; const auto pinState = _discoveryData->_syncOptions._vfs->pinState(path._local); - if (FileSystem::isLnkFile(path._local) && !_discoveryData->_syncOptions._vfs->pinState(path._local).isValid()) { - item->_type = ItemTypeVirtualFileDownload; - } else { - item->_type = ItemTypeVirtualFileDehydration; - } + item->_type = ItemTypeVirtualFileDehydration; } else if (!serverModified && (dbEntry._inode != localEntry.inode || (localEntry.isMetadataMissing && item->_type == ItemTypeFile && !FileSystem::isLnkFile(item->_file)) @@ -1735,6 +1731,15 @@ void ProcessDirectoryJob::processFileFinalize( item->_instruction = CSyncEnums::CSYNC_INSTRUCTION_UPDATE_VFS_METADATA; } + if (_discoveryData->_syncOptions._vfs && + (item->_type == CSyncEnums::ItemTypeFile || item->_type == CSyncEnums::ItemTypeDirectory) && + item->_instruction == CSyncEnums::CSYNC_INSTRUCTION_NONE && + FileSystem::isLnkFile((_discoveryData->_localDir + path._local))) { + item->_instruction = CSyncEnums::CSYNC_INSTRUCTION_SYNC; + item->_direction = SyncFileItem::Down; + item->_type = CSyncEnums::ItemTypeVirtualFileDehydration; + } + if (path._original != path._target && (item->_instruction == CSYNC_INSTRUCTION_UPDATE_VFS_METADATA || item->_instruction == CSYNC_INSTRUCTION_UPDATE_METADATA || item->_instruction == CSYNC_INSTRUCTION_NONE)) { ASSERT(_dirItem && _dirItem->_instruction == CSYNC_INSTRUCTION_RENAME); // This is because otherwise subitems are not updated! (ideally renaming a directory could diff --git a/src/libsync/propagatedownload.cpp b/src/libsync/propagatedownload.cpp index 9fcc3988fb..b6474ea54d 100644 --- a/src/libsync/propagatedownload.cpp +++ b/src/libsync/propagatedownload.cpp @@ -498,6 +498,13 @@ void PropagateDownloadFile::startAfterIsEncryptedIsChecked() } qCDebug(lcPropagateDownload) << "dehydrating file" << _item->_file; + if (FileSystem::isLnkFile(fsPath)) { + const auto convertResult = vfs->convertToPlaceholder(fsPath, *_item); + if (!convertResult) { + qCCritical(lcPropagateDownload()) << "error when converting a shortcut file to placeholder" << convertResult.error(); + } + } + auto r = vfs->dehydratePlaceholder(*_item); if (!r) { done(SyncFileItem::NormalError, r.error(), ErrorCategory::GenericError); diff --git a/src/libsync/propagatorjobs.cpp b/src/libsync/propagatorjobs.cpp index bcdf5a4697..b57a4ede46 100644 --- a/src/libsync/propagatorjobs.cpp +++ b/src/libsync/propagatorjobs.cpp @@ -117,7 +117,8 @@ void PropagateLocalRemove::start() } QString removeError; - if (_moveToTrash) { + const auto availability = propagator()->syncOptions()._vfs->availability(_item->_file, Vfs::AvailabilityRecursivity::RecursiveAvailability); + if (_moveToTrash && (!availability || (*availability != VfsItemAvailability::AllDehydrated && *availability != VfsItemAvailability::OnlineOnly && *availability != VfsItemAvailability::Mixed))) { if ((QDir(filename).exists() || FileSystem::fileExists(filename)) && !FileSystem::moveToTrash(filename, &removeError)) { done(SyncFileItem::NormalError, removeError, ErrorCategory::GenericError); @@ -228,8 +229,6 @@ void PropagateLocalMkdir::startLocalMkdir() #if !defined(Q_OS_MACOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_15 if (!_item->_remotePerm.isNull() && !_item->_remotePerm.hasPermission(RemotePermissions::CanAddFile) && - !_item->_remotePerm.hasPermission(RemotePermissions::CanRename) && - !_item->_remotePerm.hasPermission(RemotePermissions::CanMove) && !_item->_remotePerm.hasPermission(RemotePermissions::CanAddSubDirectories)) { try { FileSystem::setFolderPermissions(newDirStr, FileSystem::FolderPermissions::ReadOnly); diff --git a/src/libsync/vfs/cfapi/cfapiwrapper.cpp b/src/libsync/vfs/cfapi/cfapiwrapper.cpp index a483d2c066..ed214b88f9 100644 --- a/src/libsync/vfs/cfapi/cfapiwrapper.cpp +++ b/src/libsync/vfs/cfapi/cfapiwrapper.cpp @@ -157,17 +157,17 @@ void CALLBACK cfApiFetchDataCallback(const CF_CALLBACK_INFO *callbackInfo, const callbackInfo->FileSize.QuadPart); }; - if (QCoreApplication::applicationPid() == callbackInfo->ProcessInfo->ProcessId) { - qCCritical(lcCfApiWrapper) << "implicit hydration triggered by the client itself. Will lead to a deadlock. Cancel"; - sendTransferError(); - return; - } - auto vfs = reinterpret_cast(callbackInfo->CallbackContext); Q_ASSERT(vfs->metaObject()->className() == QByteArrayLiteral("OCC::VfsCfApi")); const auto path = QString(QString::fromWCharArray(callbackInfo->VolumeDosName) + QString::fromWCharArray(callbackInfo->NormalizedPath)); const auto requestId = QString::number(callbackInfo->TransferKey.QuadPart, 16); + if (QCoreApplication::applicationPid() == callbackInfo->ProcessInfo->ProcessId) { + qCCritical(lcCfApiWrapper) << "implicit hydration triggered by the client itself. Will lead to a deadlock. Cancel" << path << requestId; + sendTransferError(); + return; + } + qCDebug(lcCfApiWrapper) << "Request hydration for" << path << requestId; const auto invokeResult = QMetaObject::invokeMethod(vfs, [=] { vfs->requestHydration(requestId, path); }, Qt::QueuedConnection); @@ -781,10 +781,12 @@ bool OCC::CfApiWrapper::isSparseFile(const QString &path) OCC::CfApiWrapper::FileHandle OCC::CfApiWrapper::handleForPath(const QString &path) { if (path.isEmpty()) { + qCWarning(lcCfApiWrapper) << "empty path"; return {}; } if (!FileSystem::fileExists(path)) { + qCWarning(lcCfApiWrapper) << "file does not exist"; return {}; } @@ -807,6 +809,7 @@ OCC::CfApiWrapper::FileHandle OCC::CfApiWrapper::handleForPath(const QString &pa } } + qCWarning(lcCfApiWrapper) << "no handle was created"; return {}; } diff --git a/src/libsync/vfs/cfapi/vfs_cfapi.cpp b/src/libsync/vfs/cfapi/vfs_cfapi.cpp index 414caed1bf..64779407f2 100644 --- a/src/libsync/vfs/cfapi/vfs_cfapi.cpp +++ b/src/libsync/vfs/cfapi/vfs_cfapi.cpp @@ -372,6 +372,14 @@ Vfs::AvailabilityResult VfsCfApi::availability(const QString &folderPath, const return VfsItemAvailability::AlwaysLocal; else return VfsItemAvailability::AllHydrated; + } else { + if (pin && *pin == PinState::OnlineOnly) { + return VfsItemAvailability::OnlineOnly; + } else if (pin && *pin == PinState::AlwaysLocal) { + return VfsItemAvailability::AlwaysLocal; + } else { + return VfsItemAvailability::AllDehydrated; + } } return AvailabilityError::NoSuchItem; } @@ -511,7 +519,7 @@ int VfsCfApi::finalizeHydrationJob(const QString &requestId) VfsCfApi::HydratationAndPinStates VfsCfApi::computeRecursiveHydrationAndPinStates(const QString &folderPath, const Optional &basePinState) { Q_ASSERT(!folderPath.endsWith('/')); - const auto fullPath = params().filesystemPath + folderPath; + const auto fullPath = QString{params().filesystemPath + folderPath}; QFileInfo info(params().filesystemPath + folderPath); if (!FileSystem::fileExists(fullPath)) {