From 5cbc179f8d1fa58ecdffe7233c8025625025e6af Mon Sep 17 00:00:00 2001 From: Camila Ayres Date: Mon, 8 Sep 2025 18:47:41 +0200 Subject: [PATCH 1/4] fix(quota): return unlimited quota if server query is invalid or file is in folder root. Signed-off-by: Camila Ayres Signed-off-by: Jyrki Gadinger --- src/libsync/discovery.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index 1ff9c5f080ff1..0d71629b4a9de 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -1085,20 +1085,28 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(const SyncFileItemPtr &it int64_t ProcessDirectoryJob::folderBytesAvailable(const SyncFileItemPtr &item, const FolderQuota::ServerEntry serverEntry) const { const auto unlimitedFreeSpace = -3; - if (item->_size == 0 || item->_direction != SyncFileItem::Up || item->isDirectory() || item->_instruction == CSYNC_INSTRUCTION_TYPE_CHANGE) { - return unlimitedFreeSpace; - } + const auto isTypeChange = item->_instruction == CSYNC_INSTRUCTION_TYPE_CHANGE; + const auto isUpdateMetadataOrRename = item->_instruction != CSYNC_INSTRUCTION_SYNC && item->_instruction != CSYNC_INSTRUCTION_NEW; + const auto isFileDownloadOrDirectory = item->_direction != SyncFileItem::Up || item->isDirectory(); - if (item->_instruction != CSYNC_INSTRUCTION_SYNC && item->_instruction != CSYNC_INSTRUCTION_NEW) { + if (item->_size == 0 || isTypeChange || isFileDownloadOrDirectory || isUpdateMetadataOrRename) { + qCInfo(lcDisco) << "Returning unlimited free space for item:" << item->_file; return unlimitedFreeSpace; } - if (serverEntry == FolderQuota::ServerEntry::Valid || !_dirItem) { + if (serverEntry == FolderQuota::ServerEntry::Valid) { + qCInfo(lcDisco) << "Returning cached _folderQuota.bytesAvailable" << _folderQuota.bytesAvailable << "for item:" << item->_file; return _folderQuota.bytesAvailable; } + if (!_dirItem) { + qCInfo(lcDisco) << "Returning unlimited free space for item with no _dirItem:" << item->_file; + return unlimitedFreeSpace; + } + SyncJournalFileRecord dirItemDbRecord; if (_discoveryData->_statedb->getFileRecord(_dirItem->_file, &dirItemDbRecord) && dirItemDbRecord.isValid()) { + qCInfo(lcDisco) << "Returning db value dirItemDbRecord._folderQuota.bytesAvailable" << dirItemDbRecord._folderQuota.bytesAvailable << "for item:" << item->_file; return dirItemDbRecord._folderQuota.bytesAvailable; } From f5decc82ea558b20fe961bb22aba7f459a2c4d02 Mon Sep 17 00:00:00 2001 From: Camila Ayres Date: Mon, 15 Sep 2025 18:18:35 +0200 Subject: [PATCH 2/4] chore: print sync information when checking quota. Signed-off-by: Camila Ayres Signed-off-by: Jyrki Gadinger --- src/libsync/discovery.cpp | 31 +++++++++++++++++++++++++------ src/libsync/discoveryphase.cpp | 14 +++++++++----- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index 0d71629b4a9de..776f154b04175 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -1089,27 +1089,41 @@ int64_t ProcessDirectoryJob::folderBytesAvailable(const SyncFileItemPtr &item, c const auto isUpdateMetadataOrRename = item->_instruction != CSYNC_INSTRUCTION_SYNC && item->_instruction != CSYNC_INSTRUCTION_NEW; const auto isFileDownloadOrDirectory = item->_direction != SyncFileItem::Up || item->isDirectory(); + qCInfo(lcDisco) << "Checking quota for item:" << item->_file + << "isTypeChange?" << isTypeChange + << "isUpdateMetadataOrRename?" << isUpdateMetadataOrRename + << "isFileDownloadOrDirectory?" << isFileDownloadOrDirectory + << "_dirItem?" << _dirItem + << "_dirParentItem?" << _dirParentItem + << "item->_size:" << item->_size + << "_folderQuota.bytesAvailable:" << _folderQuota.bytesAvailable + << "_folderQuota.bytesUsed:" << _folderQuota.bytesUsed; + if (item->_size == 0 || isTypeChange || isFileDownloadOrDirectory || isUpdateMetadataOrRename) { - qCInfo(lcDisco) << "Returning unlimited free space for item:" << item->_file; + qCInfo(lcDisco) << "Returning unlimited free space (-3) for item quota."; return unlimitedFreeSpace; } if (serverEntry == FolderQuota::ServerEntry::Valid) { - qCInfo(lcDisco) << "Returning cached _folderQuota.bytesAvailable" << _folderQuota.bytesAvailable << "for item:" << item->_file; + qCInfo(lcDisco) << "Returning cached _folderQuota.bytesAvailable for item quota."; return _folderQuota.bytesAvailable; } if (!_dirItem) { - qCInfo(lcDisco) << "Returning unlimited free space for item with no _dirItem:" << item->_file; + qCInfo(lcDisco) << "Returning unlimited free space (-3) for item quota with no _dirItem."; return unlimitedFreeSpace; } + qCInfo(lcDisco) << "_dirItem->_folderQuota.bytesAvailable:" << _dirItem->_folderQuota.bytesAvailable; + SyncJournalFileRecord dirItemDbRecord; if (_discoveryData->_statedb->getFileRecord(_dirItem->_file, &dirItemDbRecord) && dirItemDbRecord.isValid()) { - qCInfo(lcDisco) << "Returning db value dirItemDbRecord._folderQuota.bytesAvailable" << dirItemDbRecord._folderQuota.bytesAvailable << "for item:" << item->_file; - return dirItemDbRecord._folderQuota.bytesAvailable; + const auto dirDbBytesAvailable = dirItemDbRecord._folderQuota.bytesAvailable; + qCInfo(lcDisco) << "Returning for item quota db value dirItemDbRecord._folderQuota.bytesAvailable" << dirDbBytesAvailable; + return dirDbBytesAvailable; } + qCInfo(lcDisco) << "Returning _dirItem->_folderQuota.bytesAvailable for item quota."; return _dirItem->_folderQuota.bytesAvailable; } @@ -2262,7 +2276,9 @@ DiscoverySingleDirectoryJob *ProcessDirectoryJob::startAsyncServerQuery() Q_ASSERT(_dirItem->_e2eEncryptionStatus != SyncFileItem::EncryptionStatus::NotEncrypted); _discoveryData->_anotherSyncNeeded = !alreadyDownloaded && serverJob->encryptedMetadataNeedUpdate(); } - qCInfo(lcDisco) << "serverJob has finished for folder:" << _dirItem->_file << " and it has _isFileDropDetected:" << _dirItem->_isFileDropDetected; + qCInfo(lcDisco) << "serverJob has finished for folder:" << _dirItem->_file << " and it has _isFileDropDetected:" << _dirItem->_isFileDropDetected + << "with quota bytesUSed:" << _dirItem->_folderQuota.bytesUsed + << "bytesAvailable:" << _dirItem->_folderQuota.bytesAvailable; } _discoveryData->_currentlyActiveJobs--; _pendingAsyncJobs--; @@ -2304,6 +2320,9 @@ DiscoverySingleDirectoryJob *ProcessDirectoryJob::startAsyncServerQuery() void ProcessDirectoryJob::setFolderQuota(const FolderQuota &folderQuota) { + qCInfo(lcDisco) << "Setting quota for folder" << _discoveryData->_localDir + _currentFolder._local + << "bytes used:" << folderQuota.bytesUsed + << "bytes available:" << folderQuota.bytesAvailable; _folderQuota.bytesUsed = folderQuota.bytesUsed; _folderQuota.bytesAvailable = folderQuota.bytesAvailable; } diff --git a/src/libsync/discoveryphase.cpp b/src/libsync/discoveryphase.cpp index 16e7c8822e0bf..83b725143decf 100644 --- a/src/libsync/discoveryphase.cpp +++ b/src/libsync/discoveryphase.cpp @@ -624,9 +624,12 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(const QString &fi } // all folders will contain both - if (map.contains(FolderQuota::usedBytesC) && map.contains(FolderQuota::availableBytesC)) { + if (map.contains(FolderQuota::usedBytesC) && map.contains(FolderQuota::availableBytesC)) { _folderQuota = {map.value(FolderQuota::usedBytesC).toLongLong(), map.value(FolderQuota::availableBytesC).toLongLong()}; + qCWarning(lcDiscovery) << "Setting quota for" << file + << "bytesUsed:" << _folderQuota.bytesUsed + << "bytesAvailable:" << _folderQuota.bytesAvailable; emit setfolderQuota(_folderQuota); } } else { @@ -634,11 +637,12 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(const QString &fi int slash = file.lastIndexOf('/'); result.name = file.mid(slash + 1); result.size = -1; - if (map.contains(FolderQuota::usedBytesC)) { - result.folderQuota.bytesUsed = map.value(FolderQuota::usedBytesC).toLongLong(); - } - if (map.contains(FolderQuota::availableBytesC)) { + if (map.contains(FolderQuota::usedBytesC) && map.contains(FolderQuota::availableBytesC)) { result.folderQuota.bytesAvailable = map.value(FolderQuota::availableBytesC).toLongLong(); + result.folderQuota.bytesUsed = map.value(FolderQuota::usedBytesC).toLongLong(); + qCWarning(lcDiscovery) << "Setting quota for" << file + << "bytesUsed:" << result.folderQuota.bytesUsed + << "bytesAvailable:" << result.folderQuota.bytesAvailable; } propertyMapToRemoteInfo(map, _account->serverHasMountRootProperty() ? RemotePermissions::MountedPermissionAlgorithm::UseMountRootProperty : RemotePermissions::MountedPermissionAlgorithm::WildGuessMountedSubProperty, From 4a37e73eba161e8152aa14cfc338ab8a59f207b0 Mon Sep 17 00:00:00 2001 From: Jyrki Gadinger Date: Fri, 10 Oct 2025 10:09:00 +0200 Subject: [PATCH 3/4] fix(discovery): remove extra check for valid server entry `processFileAnalyzeRemoteInfo` is only called iff `serverEntry.isValid` anyway Signed-off-by: Jyrki Gadinger --- src/libsync/discovery.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index 776f154b04175..bab0c274fb225 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -756,13 +756,8 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(const SyncFileItemPtr &it item->_isLivePhoto = serverEntry.isLivePhoto; item->_livePhotoFile = serverEntry.livePhotoFile; - if (serverEntry.isValid()) { - item->_folderQuota.bytesUsed = serverEntry.folderQuota.bytesUsed; - item->_folderQuota.bytesAvailable = serverEntry.folderQuota.bytesAvailable; - } else { - item->_folderQuota.bytesUsed = -1; - item->_folderQuota.bytesAvailable = -1; - } + item->_folderQuota.bytesUsed = serverEntry.folderQuota.bytesUsed; + item->_folderQuota.bytesAvailable = serverEntry.folderQuota.bytesAvailable; // Check for missing server data { From 7ad0fa4ccde12fbec219fc24955041fb2069cf24 Mon Sep 17 00:00:00 2001 From: Jyrki Gadinger Date: Fri, 10 Oct 2025 10:25:36 +0200 Subject: [PATCH 4/4] chore: change the extra quota logging to debug level Signed-off-by: Jyrki Gadinger --- src/libsync/discovery.cpp | 42 +++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index bab0c274fb225..588d0dc9037a7 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -1084,41 +1084,41 @@ int64_t ProcessDirectoryJob::folderBytesAvailable(const SyncFileItemPtr &item, c const auto isUpdateMetadataOrRename = item->_instruction != CSYNC_INSTRUCTION_SYNC && item->_instruction != CSYNC_INSTRUCTION_NEW; const auto isFileDownloadOrDirectory = item->_direction != SyncFileItem::Up || item->isDirectory(); - qCInfo(lcDisco) << "Checking quota for item:" << item->_file - << "isTypeChange?" << isTypeChange - << "isUpdateMetadataOrRename?" << isUpdateMetadataOrRename - << "isFileDownloadOrDirectory?" << isFileDownloadOrDirectory - << "_dirItem?" << _dirItem - << "_dirParentItem?" << _dirParentItem - << "item->_size:" << item->_size - << "_folderQuota.bytesAvailable:" << _folderQuota.bytesAvailable - << "_folderQuota.bytesUsed:" << _folderQuota.bytesUsed; + qCDebug(lcDisco) << "Checking quota for item:" << item->_file + << "isTypeChange?" << isTypeChange + << "isUpdateMetadataOrRename?" << isUpdateMetadataOrRename + << "isFileDownloadOrDirectory?" << isFileDownloadOrDirectory + << "_dirItem?" << _dirItem + << "_dirParentItem?" << _dirParentItem + << "item->_size:" << item->_size + << "_folderQuota.bytesAvailable:" << _folderQuota.bytesAvailable + << "_folderQuota.bytesUsed:" << _folderQuota.bytesUsed; if (item->_size == 0 || isTypeChange || isFileDownloadOrDirectory || isUpdateMetadataOrRename) { - qCInfo(lcDisco) << "Returning unlimited free space (-3) for item quota."; + qCDebug(lcDisco) << "Returning unlimited free space (-3) for item quota."; return unlimitedFreeSpace; } if (serverEntry == FolderQuota::ServerEntry::Valid) { - qCInfo(lcDisco) << "Returning cached _folderQuota.bytesAvailable for item quota."; + qCDebug(lcDisco) << "Returning cached _folderQuota.bytesAvailable for item quota."; return _folderQuota.bytesAvailable; } if (!_dirItem) { - qCInfo(lcDisco) << "Returning unlimited free space (-3) for item quota with no _dirItem."; + qCDebug(lcDisco) << "Returning unlimited free space (-3) for item quota with no _dirItem."; return unlimitedFreeSpace; } - qCInfo(lcDisco) << "_dirItem->_folderQuota.bytesAvailable:" << _dirItem->_folderQuota.bytesAvailable; + qCDebug(lcDisco) << "_dirItem->_folderQuota.bytesAvailable:" << _dirItem->_folderQuota.bytesAvailable; SyncJournalFileRecord dirItemDbRecord; if (_discoveryData->_statedb->getFileRecord(_dirItem->_file, &dirItemDbRecord) && dirItemDbRecord.isValid()) { const auto dirDbBytesAvailable = dirItemDbRecord._folderQuota.bytesAvailable; - qCInfo(lcDisco) << "Returning for item quota db value dirItemDbRecord._folderQuota.bytesAvailable" << dirDbBytesAvailable; + qCDebug(lcDisco) << "Returning for item quota db value dirItemDbRecord._folderQuota.bytesAvailable" << dirDbBytesAvailable; return dirDbBytesAvailable; } - qCInfo(lcDisco) << "Returning _dirItem->_folderQuota.bytesAvailable for item quota."; + qCDebug(lcDisco) << "Returning _dirItem->_folderQuota.bytesAvailable for item quota."; return _dirItem->_folderQuota.bytesAvailable; } @@ -2271,9 +2271,9 @@ DiscoverySingleDirectoryJob *ProcessDirectoryJob::startAsyncServerQuery() Q_ASSERT(_dirItem->_e2eEncryptionStatus != SyncFileItem::EncryptionStatus::NotEncrypted); _discoveryData->_anotherSyncNeeded = !alreadyDownloaded && serverJob->encryptedMetadataNeedUpdate(); } - qCInfo(lcDisco) << "serverJob has finished for folder:" << _dirItem->_file << " and it has _isFileDropDetected:" << _dirItem->_isFileDropDetected - << "with quota bytesUSed:" << _dirItem->_folderQuota.bytesUsed - << "bytesAvailable:" << _dirItem->_folderQuota.bytesAvailable; + qCDebug(lcDisco) << "serverJob has finished for folder:" << _dirItem->_file << " and it has _isFileDropDetected:" << _dirItem->_isFileDropDetected + << "with quota bytesUsed:" << _dirItem->_folderQuota.bytesUsed + << "bytesAvailable:" << _dirItem->_folderQuota.bytesAvailable; } _discoveryData->_currentlyActiveJobs--; _pendingAsyncJobs--; @@ -2315,9 +2315,9 @@ DiscoverySingleDirectoryJob *ProcessDirectoryJob::startAsyncServerQuery() void ProcessDirectoryJob::setFolderQuota(const FolderQuota &folderQuota) { - qCInfo(lcDisco) << "Setting quota for folder" << _discoveryData->_localDir + _currentFolder._local - << "bytes used:" << folderQuota.bytesUsed - << "bytes available:" << folderQuota.bytesAvailable; + qCDebug(lcDisco) << "Setting quota for folder" << _discoveryData->_localDir + _currentFolder._local + << "bytes used:" << folderQuota.bytesUsed + << "bytes available:" << folderQuota.bytesAvailable; _folderQuota.bytesUsed = folderQuota.bytesUsed; _folderQuota.bytesAvailable = folderQuota.bytesAvailable; }