From: Christian Kamm Date: Wed, 13 Feb 2019 13:18:54 +0000 (+0100) Subject: Ensure local discovery on selective sync changes X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~12^2~21^2~468^2~288 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=238ac536662256ba14ebeabad7f67a19043963fb;p=nextcloud-desktop.git Ensure local discovery on selective sync changes As far as I'm aware local discovery can be skipped on folders that are selective-sync blacklisted, so a local discovery is required when an entry is removed from the blacklist. Also rename avoidReadFromDbOnNextSync() -> schedulePathForRemoteDiscovery() since the old name might also imply it's not read from db in the local discovery - which is not the case. Use Folder:: schedulePathForLocalDiscovery() for that. --- diff --git a/src/cmd/cmd.cpp b/src/cmd/cmd.cpp index bb6365aa2..12dbb2721 100644 --- a/src/cmd/cmd.cpp +++ b/src/cmd/cmd.cpp @@ -303,7 +303,7 @@ void selectiveSyncFixup(OCC::SyncJournalDb *journal, const QStringList &newList) auto blackListSet = newList.toSet(); const auto changes = (oldBlackListSet - blackListSet) + (blackListSet - oldBlackListSet); for (const auto &it : changes) { - journal->avoidReadFromDbOnNextSync(it); + journal->schedulePathForRemoteDiscovery(it); } journal->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, newList); diff --git a/src/common/syncjournaldb.cpp b/src/common/syncjournaldb.cpp index 37ec908da..d4b0f2f83 100644 --- a/src/common/syncjournaldb.cpp +++ b/src/common/syncjournaldb.cpp @@ -1819,10 +1819,10 @@ void SyncJournalDb::avoidRenamesOnNextSync(const QByteArray &path) // We also need to remove the ETags so the update phase refreshes the directory paths // on the next sync - avoidReadFromDbOnNextSync(path); + schedulePathForRemoteDiscovery(path); } -void SyncJournalDb::avoidReadFromDbOnNextSync(const QByteArray &fileName) +void SyncJournalDb::schedulePathForRemoteDiscovery(const QByteArray &fileName) { QMutexLocker locker(&_mutex); @@ -2077,7 +2077,7 @@ void SyncJournalDb::markVirtualFileForDownloadRecursively(const QByteArray &path query.bindValue(1, path); query.exec(); - // We also must make sure we do not read the files from the database (same logic as in avoidReadFromDbOnNextSync) + // We also must make sure we do not read the files from the database (same logic as in schedulePathForRemoteDiscovery) // This includes all the parents up to the root, but also all the directory within the selected dir. static_assert(ItemTypeDirectory == 2, ""); query.prepare("UPDATE metadata SET md5='_invalid_' WHERE " diff --git a/src/common/syncjournaldb.h b/src/common/syncjournaldb.h index d176b6957..7f95b85d2 100644 --- a/src/common/syncjournaldb.h +++ b/src/common/syncjournaldb.h @@ -169,8 +169,8 @@ public: * Any setFileRecord() call to affected directories before the next sync run will be * adjusted to retain the invalid etag via _etagStorageFilter. */ - void avoidReadFromDbOnNextSync(const QString &fileName) { avoidReadFromDbOnNextSync(fileName.toUtf8()); } - void avoidReadFromDbOnNextSync(const QByteArray &fileName); + void schedulePathForRemoteDiscovery(const QString &fileName) { schedulePathForRemoteDiscovery(fileName.toUtf8()); } + void schedulePathForRemoteDiscovery(const QByteArray &fileName); /** * Wipe _etagStorageFilter. Also done implicitly on close(). @@ -180,7 +180,7 @@ public: /** * Ensures full remote discovery happens on the next sync. * - * Equivalent to calling avoidReadFromDbOnNextSync() for all files. + * Equivalent to calling schedulePathForRemoteDiscovery() for all files. */ void forceRemoteDiscoveryNextSync(); @@ -390,7 +390,7 @@ private: /* Storing etags to these folders, or their parent folders, is filtered out. * - * When avoidReadFromDbOnNextSync() is called some etags to _invalid_ in the + * When schedulePathForRemoteDiscovery() is called some etags to _invalid_ in the * database. If this is done during a sync run, a later propagation job might * undo that by writing the correct etag to the database instead. This filter * will prevent this write and instead guarantee the _invalid_ etag stays in diff --git a/src/gui/accountsettings.cpp b/src/gui/accountsettings.cpp index 1cff6c12f..c8e767044 100644 --- a/src/gui/accountsettings.cpp +++ b/src/gui/accountsettings.cpp @@ -662,7 +662,8 @@ void AccountSettings::slotEnableVfsCurrentFolder() auto oldBlacklist = folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, &ok); folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, {}); for (const auto &entry : oldBlacklist) { - folder->journalDb()->avoidReadFromDbOnNextSync(entry); + folder->journalDb()->schedulePathForRemoteDiscovery(entry); + folder->schedulePathForLocalDiscovery(entry); } // Change the folder vfs mode and load the plugin diff --git a/src/gui/folder.cpp b/src/gui/folder.cpp index c5bcbcd16..8bc375571 100644 --- a/src/gui/folder.cpp +++ b/src/gui/folder.cpp @@ -603,8 +603,9 @@ void Folder::downloadVirtualFile(const QString &_relativepath) if (record._type == ItemTypeVirtualFile) { record._type = ItemTypeVirtualFileDownload; _journal.setFileRecord(record); - // Make sure we go over that file during the discovery - _journal.avoidReadFromDbOnNextSync(relativepath); + // Make sure we go over that file during the discovery even if + // no actual remote discovery would be necessary + _journal.schedulePathForRemoteDiscovery(relativepath); } else if (record._type == ItemTypeDirectory || relativepath.isEmpty()) { _journal.markVirtualFileForDownloadRecursively(relativepath); } else { @@ -1125,6 +1126,11 @@ void Folder::slotNextSyncFullLocalDiscovery() _timeSinceLastFullLocalDiscovery.invalidate(); } +void Folder::schedulePathForLocalDiscovery(const QString &relativePath) +{ + _localDiscoveryTracker->addTouchedPath(relativePath.toUtf8()); +} + void Folder::slotFolderConflicts(const QString &folder, const QStringList &conflictPaths) { if (folder != _definition.alias) diff --git a/src/gui/folder.h b/src/gui/folder.h index 75fe0b2c5..d836952de 100644 --- a/src/gui/folder.h +++ b/src/gui/folder.h @@ -348,6 +348,14 @@ public slots: */ void dehydrateFile(const QString &relativepath); + /** Adds the path to the local discovery list + * + * A weaker version of slotNextSyncFullLocalDiscovery() that just + * schedules all parent and child items of the path for local + * discovery. + */ + void schedulePathForLocalDiscovery(const QString &relativePath); + private slots: void slotSyncStarted(); void slotSyncFinished(bool); diff --git a/src/gui/folderstatusmodel.cpp b/src/gui/folderstatusmodel.cpp index 4b6196288..562363ac4 100644 --- a/src/gui/folderstatusmodel.cpp +++ b/src/gui/folderstatusmodel.cpp @@ -871,7 +871,8 @@ void FolderStatusModel::slotApplySelectiveSync() //The part that changed should not be read from the DB on next sync because there might be new folders // (the ones that are no longer in the blacklist) foreach (const auto &it, changes) { - folder->journalDb()->avoidReadFromDbOnNextSync(it); + folder->journalDb()->schedulePathForRemoteDiscovery(it); + folder->schedulePathForLocalDiscovery(it); } FolderMan::instance()->scheduleFolder(folder); } @@ -1177,7 +1178,8 @@ void FolderStatusModel::slotSyncAllPendingBigFolders() // The part that changed should not be read from the DB on next sync because there might be new folders // (the ones that are no longer in the blacklist) foreach (const auto &it, undecidedList) { - folder->journalDb()->avoidReadFromDbOnNextSync(it); + folder->journalDb()->schedulePathForRemoteDiscovery(it); + folder->schedulePathForLocalDiscovery(it); } FolderMan::instance()->scheduleFolder(folder); } diff --git a/src/gui/selectivesyncdialog.cpp b/src/gui/selectivesyncdialog.cpp index 42e69799b..8a3e08e09 100644 --- a/src/gui/selectivesyncdialog.cpp +++ b/src/gui/selectivesyncdialog.cpp @@ -497,7 +497,8 @@ void SelectiveSyncDialog::accept() auto blackListSet = blackList.toSet(); auto changes = (oldBlackListSet - blackListSet) + (blackListSet - oldBlackListSet); foreach (const auto &it, changes) { - _folder->journalDb()->avoidReadFromDbOnNextSync(it); + _folder->journalDb()->schedulePathForRemoteDiscovery(it); + _folder->schedulePathForLocalDiscovery(it); } folderMan->scheduleFolder(_folder); diff --git a/src/gui/sharemanager.cpp b/src/gui/sharemanager.cpp index ed1eea9cc..9c8482250 100644 --- a/src/gui/sharemanager.cpp +++ b/src/gui/sharemanager.cpp @@ -38,7 +38,7 @@ static void updateFolder(const AccountPtr &account, const QString &path) // Workaround the fact that the server does not invalidate the etags of parent directories // when something is shared. auto relative = path.midRef(f->remotePathTrailingSlash().length()); - f->journalDb()->avoidReadFromDbOnNextSync(relative.toString()); + f->journalDb()->schedulePathForRemoteDiscovery(relative.toString()); // Schedule a sync so it can update the remote permission flag and let the socket API // know about the shared icon. diff --git a/src/libsync/propagatedownload.cpp b/src/libsync/propagatedownload.cpp index a14147ae4..c0a5e250b 100644 --- a/src/libsync/propagatedownload.cpp +++ b/src/libsync/propagatedownload.cpp @@ -688,7 +688,7 @@ void PropagateDownloadFile::slotGetFinished() // As a precaution against bugs that cause our database and the // reality on the server to diverge, rediscover this folder on the // next sync run. - propagator()->_journal->avoidReadFromDbOnNextSync(_item->_file); + propagator()->_journal->schedulePathForRemoteDiscovery(_item->_file); } QByteArray errorBody; diff --git a/src/libsync/propagateupload.cpp b/src/libsync/propagateupload.cpp index 6e237efc5..2ea539e16 100644 --- a/src/libsync/propagateupload.cpp +++ b/src/libsync/propagateupload.cpp @@ -643,7 +643,7 @@ void PropagateUploadFileCommon::commonErrorHandling(AbstractNetworkJob *job) // Maybe the bad etag is in the database, we need to clear the // parent folder etag so we won't read from DB next sync. - propagator()->_journal->avoidReadFromDbOnNextSync(_item->_file); + propagator()->_journal->schedulePathForRemoteDiscovery(_item->_file); propagator()->_anotherSyncNeeded = true; } diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index 5ca33e189..4baff6cb1 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -491,7 +491,7 @@ void SyncEngine::startSync() } // Functionality like selective sync might have set up etag storage - // filtering via avoidReadFromDbOnNextSync(). This *is* the next sync, so + // filtering via schedulePathForRemoteDiscovery(). This *is* the next sync, so // undo the filter to allow this sync to retrieve and store the correct etags. _journal->clearEtagStorageFilter(); diff --git a/test/testselectivesync.cpp b/test/testselectivesync.cpp index c6278866b..c91bd8b76 100644 --- a/test/testselectivesync.cpp +++ b/test/testselectivesync.cpp @@ -69,7 +69,7 @@ private slots: auto oldSync = fakeFolder.currentLocalState(); // syncing again should do the same - fakeFolder.syncEngine().journal()->avoidReadFromDbOnNextSync(QString("A/newBigDir")); + fakeFolder.syncEngine().journal()->schedulePathForRemoteDiscovery(QString("A/newBigDir")); QVERIFY(fakeFolder.syncOnce()); QCOMPARE(fakeFolder.currentLocalState(), oldSync); QCOMPARE(newBigFolder.count(), 1); // (since we don't have a real Folder, the files were not added to any list) @@ -80,7 +80,7 @@ private slots: // Simulate that we accept all files by seting a wildcard white list fakeFolder.syncEngine().journal()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncWhiteList, QStringList() << QLatin1String("/")); - fakeFolder.syncEngine().journal()->avoidReadFromDbOnNextSync(QString("A/newBigDir")); + fakeFolder.syncEngine().journal()->schedulePathForRemoteDiscovery(QString("A/newBigDir")); QVERIFY(fakeFolder.syncOnce()); QCOMPARE(newBigFolder.count(), 0); QCOMPARE(sizeRequests.count(), 0); diff --git a/test/testsyncengine.cpp b/test/testsyncengine.cpp index ed13ab245..f4e0ad162 100644 --- a/test/testsyncengine.cpp +++ b/test/testsyncengine.cpp @@ -171,7 +171,7 @@ private slots: // Remove subFolderA with selectiveSync: fakeFolder.syncEngine().journal()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, {"parentFolder/subFolderA/"}); - fakeFolder.syncEngine().journal()->avoidReadFromDbOnNextSync(QByteArrayLiteral("parentFolder/subFolderA/")); + fakeFolder.syncEngine().journal()->schedulePathForRemoteDiscovery(QByteArrayLiteral("parentFolder/subFolderA/")); auto getEtag = [&](const QByteArray &file) { SyncJournalFileRecord rec; fakeFolder.syncJournal().getFileRecord(file, &rec); diff --git a/test/testsyncjournaldb.cpp b/test/testsyncjournaldb.cpp index b59de4376..d8d663b9c 100644 --- a/test/testsyncjournaldb.cpp +++ b/test/testsyncjournaldb.cpp @@ -236,7 +236,7 @@ private slots: makeEntry("foodir/subdir/subsubdir/file", ItemTypeFile); makeEntry("foodir/subdir/otherdir", ItemTypeDirectory); - _db.avoidReadFromDbOnNextSync(QByteArray("foodir/subdir")); + _db.schedulePathForRemoteDiscovery(QByteArray("foodir/subdir")); // Direct effects of parent directories being set to _invalid_ QCOMPARE(getEtag("foodir"), invalidEtag); diff --git a/test/testsyncmove.cpp b/test/testsyncmove.cpp index 66968afca..e78f15cc3 100644 --- a/test/testsyncmove.cpp +++ b/test/testsyncmove.cpp @@ -126,7 +126,7 @@ private slots: // Remove subFolderA with selectiveSync: fakeFolder.syncEngine().journal()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, { "parentFolder/subFolderA/" }); - fakeFolder.syncEngine().journal()->avoidReadFromDbOnNextSync(QByteArrayLiteral("parentFolder/subFolderA/")); + fakeFolder.syncEngine().journal()->schedulePathForRemoteDiscovery(QByteArrayLiteral("parentFolder/subFolderA/")); fakeFolder.syncOnce(); diff --git a/test/testsyncvirtualfiles.cpp b/test/testsyncvirtualfiles.cpp index ce140c0b8..730f879cf 100644 --- a/test/testsyncvirtualfiles.cpp +++ b/test/testsyncvirtualfiles.cpp @@ -44,7 +44,7 @@ void triggerDownload(FakeFolder &folder, const QByteArray &path) return; record._type = ItemTypeVirtualFileDownload; journal.setFileRecord(record); - journal.avoidReadFromDbOnNextSync(record._path); + journal.schedulePathForRemoteDiscovery(record._path); } void markForDehydration(FakeFolder &folder, const QByteArray &path) @@ -56,7 +56,7 @@ void markForDehydration(FakeFolder &folder, const QByteArray &path) return; record._type = ItemTypeVirtualFileDehydration; journal.setFileRecord(record); - journal.avoidReadFromDbOnNextSync(record._path); + journal.schedulePathForRemoteDiscovery(record._path); } QSharedPointer setupVfs(FakeFolder &folder)