Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/desktop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthieu Gallien <matthieu_gallien@yahoo.fr>2022-11-08 01:41:59 +0300
committerGitHub <noreply@github.com>2022-11-08 01:41:59 +0300
commitb02f1123663efd163217bd55bcdb8be5dda64dbb (patch)
treea8cf22a3a27b9dbf3c395a6c60d0cb7f1e396780
parentad8933304bee3b0553b90cd0228229997a387790 (diff)
parent402d959caea89c461366a232e807dced2c712034 (diff)
Merge pull request #5104 from nextcloud/bugfix/doNotDeleteFilesInSyncDatabase
Bugfix/delete folders during propagation even when propagation has errors
-rw-r--r--src/libsync/capabilities.cpp11
-rw-r--r--src/libsync/discovery.cpp67
-rw-r--r--src/libsync/discoveryphase.h2
-rw-r--r--src/libsync/owncloudpropagator.cpp34
-rw-r--r--src/libsync/owncloudpropagator.h9
-rw-r--r--test/testsyncmove.cpp23
6 files changed, 71 insertions, 75 deletions
diff --git a/src/libsync/capabilities.cpp b/src/libsync/capabilities.cpp
index da713b46c..1f4131e00 100644
--- a/src/libsync/capabilities.cpp
+++ b/src/libsync/capabilities.cpp
@@ -143,24 +143,27 @@ bool Capabilities::clientSideEncryptionAvailable() const
}
const auto version = properties.value(QStringLiteral("api-version"), "1.0").toByteArray();
- qCInfo(lcServerCapabilities) << "E2EE API version:" << version;
const auto splittedVersion = version.split('.');
bool ok = false;
const auto major = !splittedVersion.isEmpty() ? splittedVersion.at(0).toInt(&ok) : 0;
if (!ok) {
- qCWarning(lcServerCapabilities) << "Didn't understand version scheme (major), E2EE disabled";
+ qCWarning(lcServerCapabilities) << "Didn't understand version scheme (major), E2EE disabled" << version;
return false;
}
ok = false;
const auto minor = splittedVersion.size() > 1 ? splittedVersion.at(1).toInt(&ok) : 0;
if (!ok) {
- qCWarning(lcServerCapabilities) << "Didn't understand version scheme (minor), E2EE disabled";
+ qCWarning(lcServerCapabilities) << "Didn't understand version scheme (minor), E2EE disabled" << version;
return false;
}
- return major == 1 && minor >= 1;
+ const auto capabilityAvailable = (major == 1 && minor >= 1);
+ if (!capabilityAvailable) {
+ qCInfo(lcServerCapabilities) << "Incompatible E2EE API version:" << version;
+ }
+ return capabilityAvailable;
}
bool Capabilities::notificationsAvailable() const
diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp
index 57426dd8a..047a1bbc2 100644
--- a/src/libsync/discovery.cpp
+++ b/src/libsync/discovery.cpp
@@ -35,7 +35,7 @@
namespace OCC {
-Q_LOGGING_CATEGORY(lcDisco, "sync.discovery", QtInfoMsg)
+Q_LOGGING_CATEGORY(lcDisco, "nextcloud.sync.discovery", QtInfoMsg)
void ProcessDirectoryJob::start()
{
@@ -615,24 +615,6 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
// Unknown in db: new file on the server
Q_ASSERT(!dbEntry.isValid());
- if (!serverEntry.renameName.isEmpty()) {
- item->_renameTarget = _dirItem ? _dirItem->_file + "/" + serverEntry.renameName : serverEntry.renameName;
- item->_originalFile = path._original;
- item->_modtime = serverEntry.modtime;
- item->_size = serverEntry.size;
- item->_instruction = CSYNC_INSTRUCTION_RENAME;
- item->_direction = SyncFileItem::Up;
- item->_fileId = serverEntry.fileId;
- item->_remotePerm = serverEntry.remotePerm;
- item->_isShared = serverEntry.remotePerm.hasPermission(RemotePermissions::IsShared);
- item->_lastShareStateFetchedTimestmap = QDateTime::currentMSecsSinceEpoch();
- item->_etag = serverEntry.etag;
- item->_type = serverEntry.isDirectory ? CSyncEnums::ItemTypeDirectory : CSyncEnums::ItemTypeFile;
-
- processFileAnalyzeLocalInfo(item, path, localEntry, serverEntry, dbEntry, _queryServer);
- return;
- }
-
item->_instruction = CSYNC_INSTRUCTION_NEW;
item->_direction = SyncFileItem::Down;
item->_modtime = serverEntry.modtime;
@@ -881,41 +863,6 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
processFileFinalize(item, path, recurse, recurseQueryLocal, recurseQueryServer);
};
- auto handleInvalidSpaceRename = [&] (SyncFileItem::Direction direction) {
- if (_dirItem) {
- path._target = _dirItem->_file + "/" + localEntry.renameName;
- } else {
- path._target = localEntry.renameName;
- }
- OCC::SyncJournalFileRecord base;
- if (!_discoveryData->_statedb->getFileRecordByInode(localEntry.inode, &base)) {
- dbError();
- return;
- }
- const auto originalPath = base.path();
- const auto adjustedOriginalPath = _discoveryData->adjustRenamedPath(originalPath, SyncFileItem::Down);
- _discoveryData->_renamedItemsLocal.insert(originalPath, path._target);
- item->_renameTarget = path._target;
- path._server = adjustedOriginalPath;
- if (_dirItem) {
- item->_file = _dirItem->_file + "/" + localEntry.name;
- } else {
- item->_file = localEntry.name;
- }
- path._original = originalPath;
- item->_originalFile = path._original;
- item->_modtime = base.isValid() ? base._modtime : localEntry.modtime;
- item->_inode = base.isValid() ? base._inode : localEntry.inode;
- item->_instruction = CSYNC_INSTRUCTION_RENAME;
- item->_direction = direction;
- item->_fileId = base.isValid() ? base._fileId : QByteArray{};
- item->_remotePerm = base.isValid() ? base._remotePerm : RemotePermissions{};
- item->_etag = base.isValid() ? base._etag : QByteArray{};
- item->_type = base.isValid() ? base._type : localEntry.type;
- item->_isShared = base.isValid() ? base._isShared : false;
- item->_lastShareStateFetchedTimestmap = base.isValid() ? base._lastShareStateFetchedTimestmap : 0;
- };
-
if (!localEntry.isValid()) {
if (_queryLocal == ParentNotChanged && dbEntry.isValid()) {
// Not modified locally (ParentNotChanged)
@@ -1000,8 +947,6 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
|| _discoveryData->_syncOptions._vfs->needsMetadataUpdate(*item))) {
item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
item->_direction = SyncFileItem::Down;
- } else if (!localEntry.renameName.isEmpty()) {
- handleInvalidSpaceRename(SyncFileItem::Up);
}
} else if (!typeChange && isVfsWithSuffix()
&& dbEntry.isVirtualFile() && !localEntry.isVirtualFile
@@ -1097,16 +1042,6 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
return;
}
- if (!localEntry.renameName.isEmpty()) {
- handleInvalidSpaceRename(SyncFileItem::Down);
- item->_instruction = CSYNC_INSTRUCTION_NEW;
- item->_direction = SyncFileItem::Up;
- item->_originalFile = item->_file;
- item->_file = item->_renameTarget;
- finalize();
- return;
- }
-
// New local file or rename
item->_instruction = CSYNC_INSTRUCTION_NEW;
item->_direction = SyncFileItem::Up;
diff --git a/src/libsync/discoveryphase.h b/src/libsync/discoveryphase.h
index 0acb862d2..6c633d1bf 100644
--- a/src/libsync/discoveryphase.h
+++ b/src/libsync/discoveryphase.h
@@ -49,7 +49,6 @@ struct RemoteInfo
{
/** FileName of the entry (this does not contains any directory or path, just the plain name */
QString name;
- QString renameName;
QByteArray etag;
QByteArray fileId;
QByteArray checksumHeader;
@@ -79,7 +78,6 @@ struct LocalInfo
{
/** FileName of the entry (this does not contains any directory or path, just the plain name */
QString name;
- QString renameName;
time_t modtime = 0;
int64_t size = 0;
uint64_t inode = 0;
diff --git a/src/libsync/owncloudpropagator.cpp b/src/libsync/owncloudpropagator.cpp
index 198f1b73b..cb3734e17 100644
--- a/src/libsync/owncloudpropagator.cpp
+++ b/src/libsync/owncloudpropagator.cpp
@@ -594,7 +594,7 @@ void OwncloudPropagator::start(SyncFileItemVector &&items)
}
foreach (PropagatorJob *it, directoriesToRemove) {
- _rootJob->_dirDeletionJobs.appendJob(it);
+ _rootJob->appendDirDeletionJob(it);
}
connect(_rootJob.data(), &PropagatorJob::finished, this, &OwncloudPropagator::emitFinished);
@@ -1292,6 +1292,11 @@ qint64 PropagateRootDirectory::committedDiskSpace() const
return _subJobs.committedDiskSpace() + _dirDeletionJobs.committedDiskSpace();
}
+void PropagateRootDirectory::appendDirDeletionJob(PropagatorJob *job)
+{
+ _dirDeletionJobs.appendJob(job);
+}
+
bool PropagateRootDirectory::scheduleSelfOrChild()
{
qCInfo(lcRootDirectory()) << "scheduleSelfOrChild" << _state << "pending uploads" << propagator()->delayedTasks().size() << "subjobs state" << _subJobs._state;
@@ -1327,6 +1332,7 @@ void PropagateRootDirectory::slotSubJobsFinished(SyncFileItem::Status status)
if (status != SyncFileItem::Success
&& status != SyncFileItem::Restoration
+ && status != SyncFileItem::BlacklistedError
&& status != SyncFileItem::Conflict) {
if (_state != Finished) {
// Synchronously abort
@@ -1338,11 +1344,37 @@ void PropagateRootDirectory::slotSubJobsFinished(SyncFileItem::Status status)
return;
}
+ if (_errorStatus == SyncFileItem::NoStatus) {
+ switch (status) {
+ case SyncFileItem::NoStatus:
+ case SyncFileItem::FatalError:
+ case SyncFileItem::NormalError:
+ case SyncFileItem::SoftError:
+ case SyncFileItem::Conflict:
+ case SyncFileItem::FileIgnored:
+ case SyncFileItem::FileLocked:
+ case SyncFileItem::Restoration:
+ case SyncFileItem::FileNameInvalid:
+ case SyncFileItem::FileNameClash:
+ case SyncFileItem::DetailError:
+ case SyncFileItem::Success:
+ break;
+ case SyncFileItem::BlacklistedError:
+ _errorStatus = SyncFileItem::BlacklistedError;
+ break;
+ }
+ }
+
propagator()->scheduleNextJob();
}
void PropagateRootDirectory::slotDirDeletionJobsFinished(SyncFileItem::Status status)
{
+ if (_errorStatus != SyncFileItem::NoStatus && status == SyncFileItem::Success) {
+ qCInfo(lcPropagator) << "PropagateRootDirectory::slotDirDeletionJobsFinished" << "reporting previous error" << _errorStatus;
+ status = _errorStatus;
+ }
+
_state = Finished;
qCInfo(lcPropagator) << "PropagateRootDirectory::slotDirDeletionJobsFinished" << "emit finished" << status;
emit finished(status);
diff --git a/src/libsync/owncloudpropagator.h b/src/libsync/owncloudpropagator.h
index 87e695afc..95fe4e743 100644
--- a/src/libsync/owncloudpropagator.h
+++ b/src/libsync/owncloudpropagator.h
@@ -365,8 +365,6 @@ class OWNCLOUDSYNC_EXPORT PropagateRootDirectory : public PropagateDirectory
{
Q_OBJECT
public:
- PropagatorCompositeJob _dirDeletionJobs;
-
explicit PropagateRootDirectory(OwncloudPropagator *propagator);
bool scheduleSelfOrChild() override;
@@ -375,6 +373,9 @@ public:
[[nodiscard]] qint64 committedDiskSpace() const override;
+public slots:
+ void appendDirDeletionJob(PropagatorJob *job);
+
private slots:
void slotSubJobsFinished(SyncFileItem::Status status) override;
void slotDirDeletionJobsFinished(SyncFileItem::Status status);
@@ -382,6 +383,10 @@ private slots:
private:
bool scheduleDelayedJobs();
+
+ PropagatorCompositeJob _dirDeletionJobs;
+
+ SyncFileItem::Status _errorStatus = SyncFileItem::Status::NoStatus;
};
/**
diff --git a/test/testsyncmove.cpp b/test/testsyncmove.cpp
index f1488c818..c8f5ac2d6 100644
--- a/test/testsyncmove.cpp
+++ b/test/testsyncmove.cpp
@@ -890,6 +890,29 @@ private slots:
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
+ void testRenameParallelismWithBlacklist()
+ {
+ constexpr auto testFileName = "blackListFile";
+ FakeFolder fakeFolder{ FileInfo{} };
+ fakeFolder.remoteModifier().mkdir("A");
+ fakeFolder.remoteModifier().insert("A/file");
+
+ QVERIFY(fakeFolder.syncOnce());
+ QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+
+ fakeFolder.remoteModifier().insert(testFileName);
+ fakeFolder.serverErrorPaths().append(testFileName, 500); // will be blacklisted
+ QVERIFY(!fakeFolder.syncOnce());
+
+ fakeFolder.remoteModifier().mkdir("B");
+ fakeFolder.remoteModifier().rename("A/file", "B/file");
+ fakeFolder.remoteModifier().remove("A");
+
+ QVERIFY(!fakeFolder.syncOnce());
+ auto folderA = fakeFolder.currentLocalState().find("A");
+ QCOMPARE(folderA, nullptr);
+ }
+
void testMovedWithError_data()
{
QTest::addColumn<Vfs::Mode>("vfsMode");