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:
authorallexzander <blackslayer4@gmail.com>2021-07-13 16:56:31 +0300
committerallexzander (Rebase PR Action) <allexzander@users.noreply.github.com>2021-08-20 15:57:22 +0300
commit289df252b56d1db7573692c57ba6d50b1af52e7b (patch)
treed6e8b0823ae6aa3b4dbbf8019253cd5117662a73 /src/libsync/discovery.cpp
parentc28cac8479858215b68a4056e5e5b9e123c04631 (diff)
VFS + E2EE. Handle scenario of sync journal deleted.
Signed-off-by: allexzander <blackslayer4@gmail.com>
Diffstat (limited to 'src/libsync/discovery.cpp')
-rw-r--r--src/libsync/discovery.cpp72
1 files changed, 39 insertions, 33 deletions
diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp
index 8252c82fc..555a2d195 100644
--- a/src/libsync/discovery.cpp
+++ b/src/libsync/discovery.cpp
@@ -460,17 +460,9 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
// The file is known in the db already
if (dbEntry.isValid()) {
- qint64 size = serverEntry.size;
-
- bool metaDataSizeNeedsUpdateForE2EEFile = false;
-
- if (dbEntry.isVirtualFile() && (!item->_encryptedFileName.isEmpty()) && size > 0) {
- // make sure we set correct size when file was downloaded previously and has now been changed on the server
- // serverEntry always includes extra CommonConstants::e2EeTagSize bytes for e2e encrypted files
- // we don't need those neither when creating a placeholder nor when storing hydrated file on disk
- size = serverEntry.size - CommonConstants::e2EeTagSize;
- metaDataSizeNeedsUpdateForE2EEFile = dbEntry._fileSize == serverEntry.size;
- }
+ const bool isVirtualE2EePlaceholder = dbEntry.isVirtualFile() && !item->_encryptedFileName.isEmpty() && serverEntry.size > 0;
+ const qint64 sizeOnServer = isVirtualE2EePlaceholder ? serverEntry.size - CommonConstants::e2EeTagSize : serverEntry.size;
+ const bool metaDataSizeNeedsUpdateForE2EeFilePlaceholder = isVirtualE2EePlaceholder && dbEntry._fileSize == serverEntry.size;
if (serverEntry.isDirectory != dbEntry.isDirectory()) {
// If the type of the entity changed, it's like NEW, but
@@ -478,7 +470,7 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
item->_instruction = CSYNC_INSTRUCTION_TYPE_CHANGE;
item->_direction = SyncFileItem::Down;
item->_modtime = serverEntry.modtime;
- item->_size = size;
+ item->_size = sizeOnServer;
} else if ((dbEntry._type == ItemTypeVirtualFileDownload || localEntry.type == ItemTypeVirtualFileDownload)
&& (localEntry.isValid() || _queryLocal == ParentNotChanged)) {
// The above check for the localEntry existing is important. Otherwise it breaks
@@ -489,7 +481,7 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
} else if (dbEntry._etag != serverEntry.etag) {
item->_direction = SyncFileItem::Down;
item->_modtime = serverEntry.modtime;
- item->_size = size;
+ item->_size = sizeOnServer;
if (serverEntry.isDirectory) {
ENFORCE(dbEntry.isDirectory());
item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
@@ -499,9 +491,10 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
} else {
item->_instruction = CSYNC_INSTRUCTION_SYNC;
}
- } else if (dbEntry._remotePerm != serverEntry.remotePerm || dbEntry._fileId != serverEntry.fileId || metaDataSizeNeedsUpdateForE2EEFile) {
- if (metaDataSizeNeedsUpdateForE2EEFile) {
- item->_size = serverEntry.size - CommonConstants::e2EeTagSize;
+ } else if (dbEntry._remotePerm != serverEntry.remotePerm || dbEntry._fileId != serverEntry.fileId || metaDataSizeNeedsUpdateForE2EeFilePlaceholder) {
+ if (metaDataSizeNeedsUpdateForE2EeFilePlaceholder) {
+ // we are updating placeholder sizes after migrating from older versions with VFS + E2EE implicit hydration not supported
+ item->_size = sizeOnServer;
}
item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
item->_direction = SyncFileItem::Down;
@@ -509,21 +502,26 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
// if (is virtual mode enabled and folder is encrypted - check if the size is the same as on the server and then - trigger server query
// to update a placeholder with corrected size (-16 Bytes)
// or, maybe, add a flag to the database - vfsE2eeSizeCorrected? if it is not set - subtract it from the placeholder's size and re-create/update a placeholder?
- QueryMode serverQueryMode = ParentNotChanged;
- if (dbEntry.isDirectory() && dbEntry._isE2eEncrypted) {
- qint64 totalSizeOfPath = 0;
- if (_discoveryData->_statedb->listFilesInPath(dbEntry.path().toUtf8(), [this, &totalSizeOfPath](const OCC::SyncJournalFileRecord &record) {
+ const QueryMode serverQueryMode = [this, &dbEntry, &serverEntry]() {
+ if (dbEntry.isDirectory() && dbEntry._isE2eEncrypted) {
+ qint64 localFolderSize = 0;
+ const auto listFilesCallback = [this, &localFolderSize](const OCC::SyncJournalFileRecord &record) {
if (record.isFile()) {
- totalSizeOfPath += record._fileSize + CommonConstants::e2EeTagSize;
+ // add CommonConstants::e2EeTagSize so we will know the size of E2EE file on the server
+ localFolderSize += record._fileSize + CommonConstants::e2EeTagSize;
} else if (record.isVirtualFile()) {
- totalSizeOfPath += record._fileSize;
+ // just a virtual file, so, the size must contain CommonConstants::e2EeTagSize if it was not corrected already
+ localFolderSize += record._fileSize;
}
- })) {
- if (totalSizeOfPath != 0 && totalSizeOfPath == serverEntry.sizeOfFolder) {
- serverQueryMode = NormalQuery;
+ };
+ if (_discoveryData->_statedb->listFilesInPath(dbEntry.path().toUtf8(), listFilesCallback)
+ && localFolderSize != 0 && localFolderSize == serverEntry.sizeOfFolder) {
+ return NormalQuery;
}
}
- }
+ return ParentNotChanged;
+ }();
+
processFileAnalyzeLocalInfo(item, path, localEntry, serverEntry, dbEntry, serverQueryMode);
return;
}
@@ -562,16 +560,24 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
&& _pinState != PinState::AlwaysLocal
&& !FileSystem::isExcludeFile(item->_file)) {
item->_type = ItemTypeVirtualFile;
- if (!item->_encryptedFileName.isEmpty()) {
- // We are syncing a file for the first time (local entry is invalid) and it is encrypted file that will be virtual once synced
- // to avoid having error of "file has changed during sync" when trying to hydrate it excplicitly - we must remove CommonConstants::e2EeTagSize bytes from the end
- // as explicit hydration does not care if these bytes are present in the placeholder or not, but, the size must not change in the middle of the sync
- // this way it works for both implicit and explicit hydration by making a placeholder size that does not includes encryption tag CommonConstants::e2EeTagSize bytes
- item->_size = serverEntry.size - CommonConstants::e2EeTagSize;
- }
if (isVfsWithSuffix())
addVirtualFileSuffix(tmp_path._original);
}
+ // a virtual file is on disk but is not in the database
+ const bool fileOnDiskIsVirtual = localEntry.isValid() && localEntry.isVirtualFile;
+ // a new virtual file
+ const bool isNewVirtualFileNotOnDiskYet = !localEntry.isValid() && item->_type == ItemTypeVirtualFile;
+
+ if ((fileOnDiskIsVirtual || isNewVirtualFileNotOnDiskYet)
+ && opts._vfs->mode() != Vfs::Off
+ && !item->_encryptedFileName.isEmpty()) {
+ // We are syncing a file for the first time (local entry is invalid) and it is encrypted file that will be virtual once synced
+ // to avoid having error of "file has changed during sync" when trying to hydrate it excplicitly - we must remove CommonConstants::e2EeTagSize bytes from the end
+ // as explicit hydration does not care if these bytes are present in the placeholder or not, but, the size must not change in the middle of the sync
+ // this way it works for both implicit and explicit hydration by making a placeholder size that does not includes encryption tag CommonConstants::e2EeTagSize bytes
+ // another scenario - we are syncing a file which is on disk but not in the database (database was removed or file was not written there yet)
+ item->_size = serverEntry.size - CommonConstants::e2EeTagSize;
+ }
processFileAnalyzeLocalInfo(item, tmp_path, localEntry, serverEntry, dbEntry, _queryServer);
};