From d986011067a32cea9cf6d3a76581fdfd3c12e4c8 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Wed, 8 Apr 2015 10:50:08 +0200 Subject: [PATCH] Sync: Fix sync of deletions during 503. #2894 --- src/libsync/syncengine.cpp | 4 +++- src/libsync/syncengine.h | 14 ++++++++++++++ src/libsync/syncjournaldb.cpp | 15 ++++++++++++--- src/libsync/syncjournaldb.h | 3 ++- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index 22adefdaf..b9ef9c45c 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -384,6 +384,7 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote ) case CSYNC_STATUS_STORAGE_UNAVAILABLE: item._errorString = QLatin1String("Directory temporarily not available on server."); item._status = SyncFileItem::SoftError; + _temporarilyUnavailablePaths.insert(item._file); break; default: Q_ASSERT("Non handled error-status"); @@ -700,6 +701,7 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult) _hasRemoveFile = false; bool walkOk = true; _seenFiles.clear(); + _temporarilyUnavailablePaths.clear(); if( csync_walk_local_tree(_csync_ctx, &treewalkLocal, 0) < 0 ) { qDebug() << "Error in local treewalk."; @@ -863,7 +865,7 @@ void SyncEngine::slotFinished() _anotherSyncNeeded = _anotherSyncNeeded || _propagator->_anotherSyncNeeded; // emit the treewalk results. - if( ! _journal->postSyncCleanup( _seenFiles ) ) { + if( ! _journal->postSyncCleanup( _seenFiles, _temporarilyUnavailablePaths ) ) { qDebug() << "Cleaning of synced "; } diff --git a/src/libsync/syncengine.h b/src/libsync/syncengine.h index 63990abcb..61066771b 100644 --- a/src/libsync/syncengine.h +++ b/src/libsync/syncengine.h @@ -159,7 +159,21 @@ private: QPointer _discoveryMainThread; QSharedPointer _propagator; QString _lastDeleted; // if the last item was a path and it has been deleted + + // After a sync, only the syncdb entries whose filenames appear in this + // set will be kept. See _temporarilyUnavailablePaths. QSet _seenFiles; + + // Some paths might be temporarily unavailable on the server, for + // example due to 503 Storage not available. Deleting information + // about the files from the database in these cases would lead to + // incorrect synchronization. + // Therefore all syncdb entries whose filename starts with one of + // the paths in this set will be kept. + // The specific case that fails otherwise is deleting a local file + // while the remote says storage not available. + QSet _temporarilyUnavailablePaths; + QThread _thread; Progress::Info _progressInfo; diff --git a/src/libsync/syncjournaldb.cpp b/src/libsync/syncjournaldb.cpp index 27b43fc90..20d6eddf3 100644 --- a/src/libsync/syncjournaldb.cpp +++ b/src/libsync/syncjournaldb.cpp @@ -698,7 +698,8 @@ SyncJournalFileRecord SyncJournalDb::getFileRecord( const QString& filename ) return rec; } -bool SyncJournalDb::postSyncCleanup(const QSet &items ) +bool SyncJournalDb::postSyncCleanup(const QSet& filepathsToKeep, + const QSet& prefixesToKeep) { QMutexLocker locker(&_mutex); @@ -719,8 +720,16 @@ bool SyncJournalDb::postSyncCleanup(const QSet &items ) while(query.next()) { const QString file = query.stringValue(1); - bool contained = items.contains(file); - if( !contained ) { + bool keep = filepathsToKeep.contains(file); + if( !keep ) { + foreach( const QString & prefix, prefixesToKeep ) { + if( file.startsWith(prefix) ) { + keep = true; + break; + } + } + } + if( !keep ) { superfluousItems.append(query.stringValue(0)); } } diff --git a/src/libsync/syncjournaldb.h b/src/libsync/syncjournaldb.h index 226224b0f..eb3bc138f 100644 --- a/src/libsync/syncjournaldb.h +++ b/src/libsync/syncjournaldb.h @@ -97,7 +97,8 @@ public: */ void avoidReadFromDbOnNextSync(const QString& fileName); - bool postSyncCleanup( const QSet& items ); + bool postSyncCleanup(const QSet& filepathsToKeep, + const QSet& prefixesToKeep); /* Because sqlite transactions is really slow, we encapsulate everything in big transactions * Commit will actually commit the transaction and create a new one. -- 2.30.2