Avoid job parallelism when uploading to an encrypted folder
authorKevin Ottens <kevin.ottens@nextcloud.com>
Wed, 1 Jul 2020 12:12:18 +0000 (14:12 +0200)
committerKevin Ottens (Rebase PR Action) <er-vin@users.noreply.github.com>
Wed, 1 Jul 2020 17:11:57 +0000 (17:11 +0000)
With the current design of the file upload this necessarily pushed to a
lock starvation on the folder. Indeed you could end up with N jobs
asking for the lock at the same time. So just avoid parallelizing for
now even though it will be slow.

We could try to optimize but that'd require some serious changes to the
sync logic on the jobs... let's stabilize first and optimize later.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
src/libsync/propagateupload.cpp

index 24b55524264c1ff00f1679ae163b26d07362956a..287c92c4f9f9569c31a7ce7ffeb419072494c651 100644 (file)
@@ -172,6 +172,33 @@ PropagateUploadFileCommon::PropagateUploadFileCommon(OwncloudPropagator *propaga
     , _uploadEncryptedHelper(nullptr)
     , _uploadingEncrypted(false)
 {
+    const auto rootPath = [=]() {
+        const auto result = propagator->_remoteFolder;
+        if (result.startsWith('/')) {
+            return result.mid(1);
+        } else {
+            return result;
+        }
+    }();
+    const auto path = _item->_file;
+    const auto slashPosition = path.lastIndexOf('/');
+    const auto parentPath = slashPosition >= 0 ? path.left(slashPosition) : QString();
+
+    SyncJournalFileRecord parentRec;
+    bool ok = propagator->_journal->getFileRecord(parentPath, &parentRec);
+    if (!ok) {
+        done(SyncFileItem::NormalError);
+        return;
+    }
+
+    const auto remoteParentPath = parentRec._e2eMangledName.isEmpty() ? parentPath : parentRec._e2eMangledName;
+    const auto absoluteRemoteParentPath = remoteParentPath.isEmpty() ? rootPath : rootPath + remoteParentPath + '/';
+    const auto account = propagator->account();
+
+    if (account->capabilities().clientSideEncryptionAvailable() &&
+        account->e2e()->isFolderEncrypted(absoluteRemoteParentPath)) {
+        _parallelism = WaitForFinished;
+    }
 }
 
 PropagatorJob::JobParallelism PropagateUploadFileCommon::parallelism()