Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/csync/csync_exclude.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/*
* libcsync -- a library to sync a directory with another
*
Expand All @@ -7,7 +7,7 @@
* SPDX-License-Identifier: LGPL-2.1-or-later
*/

#include "config_csync.h"

Check failure on line 10 in src/csync/csync_exclude.cpp

View workflow job for this annotation

GitHub Actions / build

src/csync/csync_exclude.cpp:10:10 [clang-diagnostic-error]

'config_csync.h' file not found
#include <qglobal.h>

#ifndef _GNU_SOURCE
Expand All @@ -27,6 +27,9 @@
#include <QFileInfo>
#include <QDir>
#include <QVariant>
#include <QLoggingCategory>

Q_LOGGING_CATEGORY(lcCsyncExclude, "nextcloud.csync.exclude", QtInfoMsg)

Check warning on line 32 in src/csync/csync_exclude.cpp

View workflow job for this annotation

GitHub Actions / build

src/csync/csync_exclude.cpp:32:1 [cppcoreguidelines-avoid-non-const-global-variables]

variable 'Q_LOGGING_CATEGORY' is non-const and globally accessible, consider making it const

/** Expands C-like escape sequences (in place)
*/
Expand Down Expand Up @@ -163,10 +166,16 @@
// not allow to sync those to avoid file loss/ambiguities (#416)
if (blen > 1) {
if (bname.at(blen - 1) == QLatin1Char('.')) {

return CSYNC_FILE_EXCLUDE_INVALID_CHAR;
}
}

if (OCC::FileSystem::isFileLocked(path, OCC::FileSystem::LockMode::SharedRead)) {
qCWarning(lcCsyncExclude) << path << "is locked" << "exluding it from sync";
return CSYNC_FILE_LOCKED_SILENTLY_EXCLUDED;
}

if (csync_is_windows_reserved_word(bname)) {
return CSYNC_FILE_SILENTLY_EXCLUDED;
}
Expand Down
1 change: 1 addition & 0 deletions src/csync/csync_exclude.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#ifndef _CSYNC_EXCLUDE_H
#define _CSYNC_EXCLUDE_H

#include "ocsynclib.h"

Check failure on line 13 in src/csync/csync_exclude.h

View workflow job for this annotation

GitHub Actions / build

src/csync/csync_exclude.h:13:10 [clang-diagnostic-error]

'ocsynclib.h' file not found

#include "csync.h"

Expand All @@ -37,6 +37,7 @@
CSYNC_FILE_EXCLUDE_SERVER_BLACKLISTED,
CSYNC_FILE_EXCLUDE_LEADING_SPACE,
CSYNC_FILE_EXCLUDE_LEADING_AND_TRAILING_SPACE,
CSYNC_FILE_LOCKED_SILENTLY_EXCLUDED,

Check warning on line 40 in src/csync/csync_exclude.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this identifier to be shorter or equal to 31 characters.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ3O_7OcbhWNmOLW9ZLu&open=AZ3O_7OcbhWNmOLW9ZLu&pullRequest=9917
};

class ExcludedFilesTest;
Expand Down
5 changes: 5 additions & 0 deletions src/gui/folder.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2014 ownCloud GmbH
* SPDX-License-Identifier: GPL-2.0-or-later
*/

#include "common/syncjournaldb.h"

Check failure on line 7 in src/gui/folder.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/folder.cpp:7:10 [clang-diagnostic-error]

'common/syncjournaldb.h' file not found
#include "config.h"

#include "account.h"
Expand Down Expand Up @@ -1001,6 +1001,11 @@
return true;
}

if (OCC::FileSystem::isFileLocked(path, OCC::FileSystem::LockMode::SharedRead)) {
qCDebug(lcFolder) << path << "is locked" << "skip syncing it";
return true;
}

#ifndef OWNCLOUD_TEST
if (isFileExcludedAbsolute(path) && !Utility::isConflictFile(path)) {
qCDebug(lcFolder) << "* Ignoring file" << path;
Expand Down
12 changes: 12 additions & 0 deletions src/libsync/discovery.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/*
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2018 ownCloud GmbH
Expand Down Expand Up @@ -253,7 +253,7 @@
QTimer::singleShot(0, _discoveryData, &DiscoveryPhase::scheduleMoreJobs);
}

bool ProcessDirectoryJob::handleExcluded(const QString &path, const Entries &entries, const std::map<QString, Entries> &allEntries, const bool isHidden, const bool isBlacklisted)

Check failure on line 256 in src/libsync/discovery.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 108 to the 25 allowed.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ3O_7NEbhWNmOLW9ZLt&open=AZ3O_7NEbhWNmOLW9ZLt&pullRequest=9917
{
const auto isDirectory = entries.localEntry.isDirectory || entries.serverEntry.isDirectory;

Expand Down Expand Up @@ -354,6 +354,14 @@
}
}

if (excluded == CSYNC_NOT_EXCLUDED && OCC::FileSystem::isFileLocked(_discoveryData->_localDir + path, OCC::FileSystem::LockMode::SharedRead) &&
(!entries.dbEntry.isValid() || !entries.serverEntry.isValid() || entries.serverEntry.etag == entries.dbEntry._etag)) {
qCInfo(lcDisco) << _discoveryData->_localDir + path << "is locked" << "exluding it from sync";
excluded = CSYNC_FILE_LOCKED_SILENTLY_EXCLUDED;

emit _discoveryData->seenLockedFile(_discoveryData->_localDir + path);
}

if (excluded == CSYNC_NOT_EXCLUDED && !entries.localEntry.isSymLink) {
return false;
} else if (excluded == CSYNC_FILE_SILENTLY_EXCLUDED || excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE) {
Expand Down Expand Up @@ -384,6 +392,9 @@
case CSYNC_FILE_EXCLUDE_AND_REMOVE:
qCFatal(lcDisco) << "These were handled earlier";
break;
case CSYNC_FILE_LOCKED_SILENTLY_EXCLUDED:
item->_errorString = tr("File is locked by another application.");
break;
case CSYNC_FILE_EXCLUDE_LIST:
item->_errorString = tr("File is listed on the ignore list.");
break;
Expand Down Expand Up @@ -2456,6 +2467,7 @@
switch (excludeReason)
{
case CSYNC_NOT_EXCLUDED:
case CSYNC_FILE_LOCKED_SILENTLY_EXCLUDED:
case CSYNC_FILE_EXCLUDE_CASE_CLASH_CONFLICT:
case CSYNC_FILE_EXCLUDE_AND_REMOVE:
case CSYNC_FILE_EXCLUDE_CANNOT_ENCODE:
Expand Down
3 changes: 3 additions & 0 deletions src/libsync/discoveryphase.h
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,9 @@
void addErrorToGui(const OCC::SyncFileItem::Status status, const QString &errorMessage, const QString &subject, const OCC::ErrorCategory category);

void remnantReadOnlyFolderDiscovered(const OCC::SyncFileItemPtr &item);

/** Emitted when propagation would have problems with a locked file. */

Check warning on line 349 in src/libsync/discoveryphase.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Edit this comment to use the C++ format, i.e. "//".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ3O_7JibhWNmOLW9ZLs&open=AZ3O_7JibhWNmOLW9ZLs&pullRequest=9917
void seenLockedFile(const QString &fileName);
private slots:
void slotItemDiscovered(const OCC::SyncFileItemPtr &item);
};
Expand Down
16 changes: 10 additions & 6 deletions src/libsync/propagateuploadng.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* SPDX-License-Identifier: GPL-2.0-or-later
*/

#include "config.h"

Check failure on line 7 in src/libsync/propagateuploadng.cpp

View workflow job for this annotation

GitHub Actions / build

src/libsync/propagateuploadng.cpp:7:10 [clang-diagnostic-error]

'config.h' file not found
#include "propagateupload.h"
#include "owncloudpropagator_p.h"
#include "networkjobs.h"
Expand Down Expand Up @@ -355,15 +355,19 @@
}

const auto fileName = _fileToUpload._path;
if (FileSystem::isFileLocked(fileName, FileSystem::LockMode::SharedRead)) {
// If the file is currently locked, we want to retry the sync
// when it becomes available again.
emit propagator()->seenLockedFile(fileName);

// Soft error because this is likely caused by the user modifying his files while syncing
abortWithError(SyncFileItem::FileLocked, tr("File is locked preventing syncing it", "Generic warning message when a locked file cannot be synced"));
return;
}
auto device = std::make_unique<UploadDevice>(fileName, _sent, _currentChunkSize, &propagator()->_bandwidthManager);
if (auto isLocked = FileSystem::isFileLocked(fileName, FileSystem::LockMode::SharedRead); isLocked || !device->open(QIODevice::ReadOnly)) {
if (!device->open(QIODevice::ReadOnly)) {
qCWarning(lcPropagateUploadNG) << "Could not prepare upload device: " << device->errorString();

// If the file is currently locked, we want to retry the sync
// when it becomes available again.
if (isLocked) {
emit propagator()->seenLockedFile(fileName);
}
// Soft error because this is likely caused by the user modifying his files while syncing
abortWithError(SyncFileItem::SoftError, device->errorString());
return;
Expand Down
15 changes: 9 additions & 6 deletions src/libsync/propagateuploadv1.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud GmbH
* SPDX-License-Identifier: GPL-2.0-or-later
*/

#include "config.h"

Check failure on line 7 in src/libsync/propagateuploadv1.cpp

View workflow job for this annotation

GitHub Actions / build

src/libsync/propagateuploadv1.cpp:7:10 [clang-diagnostic-error]

'config.h' file not found
#include "propagateupload.h"
#include "owncloudpropagator_p.h"
#include "networkjobs.h"
Expand Down Expand Up @@ -74,7 +74,7 @@
startNextChunk();
}

void PropagateUploadFileV1::startNextChunk()

Check warning on line 77 in src/libsync/propagateuploadv1.cpp

View workflow job for this annotation

GitHub Actions / build

src/libsync/propagateuploadv1.cpp:77:29 [readability-function-cognitive-complexity]

function 'startNextChunk' has cognitive complexity of 26 (threshold 25)
{
if (propagator()->_abortRequested)
return;
Expand Down Expand Up @@ -134,16 +134,19 @@
}

const QString fileName = _fileToUpload._path;
if (FileSystem::isFileLocked(fileName, FileSystem::LockMode::SharedRead)) {
emit propagator()->seenLockedFile(fileName);

// Soft error because this is likely caused by the user modifying his files while syncing
abortWithError(SyncFileItem::FileLocked, tr("File is locked preventing syncing it", "Generic warning message when a locked file cannot be synced"));
return;
}

auto device = std::make_unique<UploadDevice>(
fileName, chunkStart, currentChunkSize, &propagator()->_bandwidthManager);
if (auto isLocked = FileSystem::isFileLocked(fileName, FileSystem::LockMode::SharedRead); isLocked || !device->open(QIODevice::ReadOnly)) {
if (!device->open(QIODevice::ReadOnly)) {
qCWarning(lcPropagateUploadV1) << "Could not prepare upload device: " << device->errorString();

// If the file is currently locked, we want to retry the sync
// when it becomes available again.
if (isLocked) {
emit propagator()->seenLockedFile(fileName);
}
// Soft error because this is likely caused by the user modifying his files while syncing
abortWithError(SyncFileItem::SoftError, device->errorString());
return;
Expand Down
1 change: 1 addition & 0 deletions src/libsync/syncengine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,7 @@ void SyncEngine::startSync()
connect(_discoveryPhase.get(), &DiscoveryPhase::silentlyExcluded,
_syncFileStatusTracker.data(), &SyncFileStatusTracker::slotAddSilentlyExcluded);
connect(_discoveryPhase.get(), &DiscoveryPhase::remnantReadOnlyFolderDiscovered, this, &SyncEngine::remnantReadOnlyFolderDiscovered);
connect(_discoveryPhase.get(), &DiscoveryPhase::seenLockedFile, this, &SyncEngine::seenLockedFile);

ProcessDirectoryJob *discoveryJob = nullptr;

Expand Down
6 changes: 3 additions & 3 deletions test/testlockedfiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* any purpose.
*/

#include <QtTest>

Check failure on line 11 in test/testlockedfiles.cpp

View workflow job for this annotation

GitHub Actions / build

test/testlockedfiles.cpp:11:10 [clang-diagnostic-error]

'QtTest' file not found
#include "syncenginetestutils.h"
#include "lockwatcher.h"
#include <syncengine.h>
Expand Down Expand Up @@ -137,15 +137,15 @@

fakeFolder.syncEngine().setLocalDiscoveryOptions(LocalDiscoveryStyle::DatabaseAndFilesystem, tracker.localDiscoveryPaths());
tracker.startSyncPartialDiscovery();
QVERIFY(!fakeFolder.syncOnce());
QVERIFY(fakeFolder.syncOnce());

QVERIFY(seenLockedFiles.contains(fakeFolder.localPath() + "A/a1"));
QVERIFY(seenLockedFiles.size() == 1);
QVERIFY(hasLocalDiscoveryPath("A/a1"));
QVERIFY(!hasLocalDiscoveryPath("A/a1"));

CloseHandle(h1);

fakeFolder.syncEngine().setLocalDiscoveryOptions(LocalDiscoveryStyle::DatabaseAndFilesystem, tracker.localDiscoveryPaths());
fakeFolder.syncEngine().setLocalDiscoveryOptions(LocalDiscoveryStyle::DatabaseAndFilesystem, {"A/a1"});
tracker.startSyncPartialDiscovery();
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
Expand Down
Loading