diff --git a/changelog/unreleased/enterprise-5052 b/changelog/unreleased/enterprise-5052 new file mode 100644 index 00000000000..afd737bdb65 --- /dev/null +++ b/changelog/unreleased/enterprise-5052 @@ -0,0 +1,6 @@ +Bugfix: Don't publish upload if we can't finish the transaction in the client + +When a file ges locked during an upload we aborted after the upload finished on the server. +Resulting in a divergence of the local and remote state which could lead to conflicts. + +https://github.com/owncloud/enterprise/issues/5052 diff --git a/src/libsync/propagateupload.cpp b/src/libsync/propagateupload.cpp index 1793d632a61..e0b657fb82a 100644 --- a/src/libsync/propagateupload.cpp +++ b/src/libsync/propagateupload.cpp @@ -570,6 +570,10 @@ void PropagateUploadFileCommon::finalize() if (quotaIt != propagator()->_folderQuota.end()) quotaIt.value() -= _item->_size; + +#ifdef Q_OS_WIN + m_fileLock.close(); +#endif // Update the database entry const auto result = propagator()->updateMetadata(*_item); if (!result) { diff --git a/src/libsync/propagateupload.h b/src/libsync/propagateupload.h index c1a24f0cea8..8abee361256 100644 --- a/src/libsync/propagateupload.h +++ b/src/libsync/propagateupload.h @@ -244,6 +244,10 @@ public slots: /** Bases headers that need to be sent on the PUT, or in the MOVE for chunking-ng */ QMap headers(); + +#ifdef Q_OS_WIN + Utility::Handle m_fileLock; +#endif }; /** diff --git a/src/libsync/propagateuploadng.cpp b/src/libsync/propagateuploadng.cpp index 3c02f948ca4..fb97efab941 100644 --- a/src/libsync/propagateuploadng.cpp +++ b/src/libsync/propagateuploadng.cpp @@ -358,6 +358,19 @@ void PropagateUploadFileNG::doFinalMove() const QUrl source = Utility::concatUrlPath(chunkUrl(), QStringLiteral("/.file")); +#ifdef Q_OS_WIN + // Try to accuire a lock on the file and keep it until we done. + // If the file is locked, abort before we perform the move on the server + const QString fileName = propagator()->fullLocalPath(_item->_file); + const auto lockMode = propagator()->syncOptions().requiredLockMode(); + m_fileLock = FileSystem::lockFile(fileName, lockMode); + if (!m_fileLock) { + emit propagator()->seenLockedFile(fileName, lockMode); + abortWithError(SyncFileItem::SoftError, tr("%1 the file is currently in use").arg(QDir::toNativeSeparators(fileName))); + return; + } +#endif + auto job = new MoveJob(propagator()->account(), source, destination, headers, this); _jobs.append(job); connect(job, &MoveJob::finishedSignal, this, &PropagateUploadFileNG::slotMoveJobFinished);