From 37b15f2406fc9de9e9c1e97faaa609a74850732d Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Mon, 4 Dec 2023 17:59:08 +0100 Subject: [PATCH 1/3] fix include order from most specific to less specific shoudl ensure that included headers are self sufficient Signed-off-by: Matthieu Gallien --- src/common/vfs.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/common/vfs.h b/src/common/vfs.h index 17a4c48e7aeb7..98757878ce3b4 100644 --- a/src/common/vfs.h +++ b/src/common/vfs.h @@ -13,17 +13,17 @@ */ #pragma once +#include "ocsynclib.h" +#include "result.h" +#include "syncfilestatus.h" +#include "pinstate.h" + #include #include #include #include -#include "ocsynclib.h" -#include "result.h" -#include "syncfilestatus.h" -#include "pinstate.h" - using csync_file_stat_t = struct csync_file_stat_s; namespace OCC { From 6e1619c0c04ebf05a9d02236d3bf9abe791af105 Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Thu, 9 Nov 2023 22:38:41 +0100 Subject: [PATCH 2/3] avoid modifying a placeholder (virtual files) when not needed acoid modifying some metadata of the placeholder when this placeholder has just been uploaded to the server (will avoid truncating the timestamps) Close #6190 Signed-off-by: Matthieu Gallien --- src/common/vfs.h | 19 +++- src/libsync/bulkpropagatorjob.cpp | 2 +- src/libsync/owncloudpropagator.cpp | 15 +-- src/libsync/owncloudpropagator.h | 15 ++- src/libsync/propagateupload.cpp | 2 +- src/libsync/vfs/cfapi/cfapiwrapper.cpp | 139 ++++++++++++++----------- src/libsync/vfs/cfapi/cfapiwrapper.h | 1 + src/libsync/vfs/cfapi/vfs_cfapi.cpp | 8 +- src/libsync/vfs/cfapi/vfs_cfapi.h | 2 +- src/libsync/vfs/suffix/vfs_suffix.cpp | 2 +- src/libsync/vfs/suffix/vfs_suffix.h | 2 +- src/libsync/vfs/xattr/vfs_xattr.cpp | 5 +- src/libsync/vfs/xattr/vfs_xattr.h | 5 +- 13 files changed, 130 insertions(+), 87 deletions(-) diff --git a/src/common/vfs.h b/src/common/vfs.h index 98757878ce3b4..efe2e6654405f 100644 --- a/src/common/vfs.h +++ b/src/common/vfs.h @@ -113,6 +113,15 @@ class OCSYNC_EXPORT Vfs : public QObject }; Q_ENUM(ConvertToPlaceholderResult) + enum UpdateMetadataType { + DatabaseMetadata = 1 << 0, + FileMetadata = 1 << 1, + AllMetadata = DatabaseMetadata | FileMetadata, + }; + + Q_DECLARE_FLAGS(UpdateMetadataTypes, UpdateMetadataType) + Q_FLAG(UpdateMetadataType) + static QString modeToString(Mode mode); static Optional modeFromString(const QString &str); @@ -203,10 +212,10 @@ class OCSYNC_EXPORT Vfs : public QObject * new placeholder shall supersede, for rename-replace actions with new downloads, * for example. */ - Q_REQUIRED_RESULT virtual Result convertToPlaceholder( - const QString &filename, - const SyncFileItem &item, - const QString &replacesFile = QString()) = 0; + Q_REQUIRED_RESULT virtual Result convertToPlaceholder(const QString &filename, + const SyncFileItem &item, + const QString &replacesFile = {}, + UpdateMetadataTypes updateType = AllMetadata) = 0; /// Determine whether the file at the given absolute path is a dehydrated placeholder. Q_REQUIRED_RESULT virtual bool isDehydratedPlaceholder(const QString &filePath) = 0; @@ -311,7 +320,7 @@ class OCSYNC_EXPORT VfsOff : public Vfs Result updateMetadata(const QString &, time_t, qint64, const QByteArray &) override { return {}; } Result createPlaceholder(const SyncFileItem &) override { return {}; } Result dehydratePlaceholder(const SyncFileItem &) override { return {}; } - Result convertToPlaceholder(const QString &, const SyncFileItem &, const QString &) override { return ConvertToPlaceholderResult::Ok; } + Result convertToPlaceholder(const QString &, const SyncFileItem &, const QString &, UpdateMetadataTypes) override { return ConvertToPlaceholderResult::Ok; } bool needsMetadataUpdate(const SyncFileItem &) override { return false; } bool isDehydratedPlaceholder(const QString &) override { return false; } diff --git a/src/libsync/bulkpropagatorjob.cpp b/src/libsync/bulkpropagatorjob.cpp index 6d83210f08839..0f0a7db3fcfa4 100644 --- a/src/libsync/bulkpropagatorjob.cpp +++ b/src/libsync/bulkpropagatorjob.cpp @@ -479,7 +479,7 @@ void BulkPropagatorJob::adjustLastJobTimeout(AbstractNetworkJob *job, qint64 fil void BulkPropagatorJob::finalizeOneFile(const BulkUploadItem &oneFile) { // Update the database entry - const auto result = propagator()->updateMetadata(*oneFile._item); + const auto result = propagator()->updateMetadata(*oneFile._item, Vfs::UpdateMetadataType::DatabaseMetadata); if (!result) { done(oneFile._item, SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error()), ErrorCategory::GenericError); return; diff --git a/src/libsync/owncloudpropagator.cpp b/src/libsync/owncloudpropagator.cpp index 488a83a3f0ff5..b2a058088c303 100644 --- a/src/libsync/owncloudpropagator.cpp +++ b/src/libsync/owncloudpropagator.cpp @@ -1001,16 +1001,19 @@ QString OwncloudPropagator::adjustRenamedPath(const QString &original) const return OCC::adjustRenamedPath(_renamedDirectories, original); } -Result OwncloudPropagator::updateMetadata(const SyncFileItem &item) +Result OwncloudPropagator::updateMetadata(const SyncFileItem &item, Vfs::UpdateMetadataTypes updateType) { - return OwncloudPropagator::staticUpdateMetadata(item, _localDir, syncOptions()._vfs.data(), _journal); + return OwncloudPropagator::staticUpdateMetadata(item, _localDir, syncOptions()._vfs.data(), _journal, updateType); } -Result OwncloudPropagator::staticUpdateMetadata(const SyncFileItem &item, const QString localDir, - Vfs *vfs, SyncJournalDb *const journal) +Result OwncloudPropagator::staticUpdateMetadata(const SyncFileItem &item, + const QString localDir, + Vfs *vfs, + SyncJournalDb *const journal, + Vfs::UpdateMetadataTypes updateType) { const QString fsPath = localDir + item.destination(); - const auto result = vfs->convertToPlaceholder(fsPath, item); + const auto result = vfs->convertToPlaceholder(fsPath, item, {}, updateType); if (!result) { return result.error(); } else if (*result == Vfs::ConvertToPlaceholderResult::Locked) { @@ -1582,7 +1585,7 @@ void CleanupPollsJob::slotPollFinished() } else if (job->_item->_status != SyncFileItem::Success) { qCWarning(lcCleanupPolls) << "There was an error with file " << job->_item->_file << job->_item->_errorString; } else { - if (!OwncloudPropagator::staticUpdateMetadata(*job->_item, _localPath, _vfs.data(), _journal)) { + if (!OwncloudPropagator::staticUpdateMetadata(*job->_item, _localPath, _vfs.data(), _journal, Vfs::AllMetadata)) { qCWarning(lcCleanupPolls) << "database error"; job->_item->_status = SyncFileItem::FatalError; job->_item->_errorString = tr("Error writing metadata to the database"); diff --git a/src/libsync/owncloudpropagator.h b/src/libsync/owncloudpropagator.h index 3dcce0712cbb7..08f87f1b3052f 100644 --- a/src/libsync/owncloudpropagator.h +++ b/src/libsync/owncloudpropagator.h @@ -27,13 +27,15 @@ #include "accountfwd.h" #include "bandwidthmanager.h" -#include "common/syncjournaldb.h" -#include "common/utility.h" #include "csync.h" #include "progressdispatcher.h" #include "syncfileitem.h" #include "syncoptions.h" +#include "common/syncjournaldb.h" +#include "common/utility.h" +#include "common/vfs.h" + #include namespace OCC { @@ -592,7 +594,7 @@ class OWNCLOUDSYNC_EXPORT OwncloudPropagator : public QObject * * Will also trigger a Vfs::convertToPlaceholder. */ - Result updateMetadata(const SyncFileItem &item); + Result updateMetadata(const SyncFileItem &item, Vfs::UpdateMetadataTypes updateType = Vfs::AllMetadata); /** Update the database for an item. * @@ -601,8 +603,11 @@ class OWNCLOUDSYNC_EXPORT OwncloudPropagator : public QObject * * Will also trigger a Vfs::convertToPlaceholder. */ - static Result staticUpdateMetadata(const SyncFileItem &item, const QString localDir, - Vfs *vfs, SyncJournalDb * const journal); + static Result staticUpdateMetadata(const SyncFileItem &item, + const QString localDir, + Vfs *vfs, + SyncJournalDb * const journal, + Vfs::UpdateMetadataTypes updateType); Q_REQUIRED_RESULT bool isDelayedUploadItem(const SyncFileItemPtr &item) const; diff --git a/src/libsync/propagateupload.cpp b/src/libsync/propagateupload.cpp index 2a7a7bbaabc89..f74727ec7bb80 100644 --- a/src/libsync/propagateupload.cpp +++ b/src/libsync/propagateupload.cpp @@ -800,7 +800,7 @@ void PropagateUploadFileCommon::finalize() quotaIt.value() -= _fileToUpload._size; // Update the database entry - const auto result = propagator()->updateMetadata(*_item); + const auto result = propagator()->updateMetadata(*_item, Vfs::DatabaseMetadata); if (!result) { done(SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error())); return; diff --git a/src/libsync/vfs/cfapi/cfapiwrapper.cpp b/src/libsync/vfs/cfapi/cfapiwrapper.cpp index ee729896300a5..bd445042dcae5 100644 --- a/src/libsync/vfs/cfapi/cfapiwrapper.cpp +++ b/src/libsync/vfs/cfapi/cfapiwrapper.cpp @@ -48,6 +48,30 @@ constexpr auto syncRootFlagsNoCfApiContextMenu = 2; constexpr auto syncRootManagerRegKey = R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SyncRootManager)"; +DWORD sizeToDWORD(size_t size) +{ + return OCC::Utility::convertSizeToDWORD(size); +} + +OCC::PinState cfPinStateToPinState(CF_PIN_STATE state) +{ + switch (state) { + case CF_PIN_STATE_UNSPECIFIED: + return OCC::PinState::Unspecified; + case CF_PIN_STATE_PINNED: + return OCC::PinState::AlwaysLocal; + case CF_PIN_STATE_UNPINNED: + return OCC::PinState::OnlineOnly; + case CF_PIN_STATE_INHERIT: + return OCC::PinState::Inherited; + case CF_PIN_STATE_EXCLUDED: + return OCC::PinState::Excluded; + default: + Q_UNREACHABLE(); + return OCC::PinState::Inherited; + } +} + void cfApiSendTransferInfo(const CF_CONNECTION_KEY &connectionKey, const CF_TRANSFER_KEY &transferKey, NTSTATUS status, void *buffer, qint64 offset, qint64 currentBlockLength, qint64 totalLength) { @@ -237,6 +261,53 @@ void CALLBACK cfApiFetchDataCallback(const CF_CALLBACK_INFO *callbackInfo, const sendTransferError(); } } + +enum class CfApiUpdateMetadataType { + OnlyBasicMetadata, + AllMetadata, +}; + +OCC::Result updatePlaceholderState(const QString &path, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath, CfApiUpdateMetadataType updateType) +{ + if (updateType == CfApiUpdateMetadataType::AllMetadata && modtime <= 0) { + return {QString{"Could not update metadata due to invalid modification time for %1: %2"}.arg(path).arg(modtime)}; + } + + const auto info = replacesPath.isEmpty() ? OCC::CfApiWrapper::findPlaceholderInfo(path) + : OCC::CfApiWrapper::findPlaceholderInfo(replacesPath); + if (!info) { + return { "Can't update non existing placeholder info" }; + } + + const auto previousPinState = cfPinStateToPinState(info->PinState); + const auto fileIdentity = QString::fromUtf8(fileId).toStdWString(); + const auto fileIdentitySize = (fileIdentity.length() + 1) * sizeof(wchar_t); + + CF_FS_METADATA metadata; + metadata.FileSize.QuadPart = size; + OCC::Utility::UnixTimeToLargeIntegerFiletime(modtime, &metadata.BasicInfo.CreationTime); + OCC::Utility::UnixTimeToLargeIntegerFiletime(modtime, &metadata.BasicInfo.LastWriteTime); + OCC::Utility::UnixTimeToLargeIntegerFiletime(modtime, &metadata.BasicInfo.LastAccessTime); + OCC::Utility::UnixTimeToLargeIntegerFiletime(modtime, &metadata.BasicInfo.ChangeTime); + metadata.BasicInfo.FileAttributes = 0; + + qCInfo(lcCfApiWrapper) << "updatePlaceholderState" << path << modtime; + const qint64 result = CfUpdatePlaceholder(OCC::CfApiWrapper::handleForPath(path).get(), updateType == CfApiUpdateMetadataType::AllMetadata ? &metadata : nullptr, + fileIdentity.data(), sizeToDWORD(fileIdentitySize), + nullptr, 0, CF_UPDATE_FLAG_MARK_IN_SYNC, nullptr, nullptr); + + if (result != S_OK) { + qCWarning(lcCfApiWrapper) << "Couldn't update placeholder info for" << path << ":" << QString::fromWCharArray(_com_error(result).ErrorMessage()) << replacesPath; + return { "Couldn't update placeholder info" }; + } + + // Pin state tends to be lost on updates, so restore it every time + if (!setPinState(path, previousPinState, OCC::CfApiWrapper::NoRecurse)) { + return { "Couldn't restore pin state" }; + } + + return OCC::Vfs::ConvertToPlaceholderResult::Ok; +} } void CALLBACK cfApiCancelFetchData(const CF_CALLBACK_INFO *callbackInfo, const CF_CALLBACK_PARAMETERS * /*callbackParameters*/) @@ -262,11 +333,6 @@ CF_CALLBACK_REGISTRATION cfApiCallbacks[] = { CF_CALLBACK_REGISTRATION_END }; -DWORD sizeToDWORD(size_t size) -{ - return OCC::Utility::convertSizeToDWORD(size); -} - void deletePlaceholderInfo(CF_PLACEHOLDER_BASIC_INFO *info) { auto byte = reinterpret_cast(info); @@ -281,25 +347,6 @@ std::wstring pathForHandle(const OCC::CfApiWrapper::FileHandle &handle) return std::wstring(buffer); } -OCC::PinState cfPinStateToPinState(CF_PIN_STATE state) -{ - switch (state) { - case CF_PIN_STATE_UNSPECIFIED: - return OCC::PinState::Unspecified; - case CF_PIN_STATE_PINNED: - return OCC::PinState::AlwaysLocal; - case CF_PIN_STATE_UNPINNED: - return OCC::PinState::OnlineOnly; - case CF_PIN_STATE_INHERIT: - return OCC::PinState::Inherited; - case CF_PIN_STATE_EXCLUDED: - return OCC::PinState::Excluded; - default: - Q_UNREACHABLE(); - return OCC::PinState::Inherited; - } -} - CF_PIN_STATE pinStateToCfPinState(OCC::PinState state) { switch (state) { @@ -750,44 +797,7 @@ OCC::Result OCC::CfApiWrapper::createPlaceholderInfo(const QStrin OCC::Result OCC::CfApiWrapper::updatePlaceholderInfo(const QString &path, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath) { - - if (modtime <= 0) { - return {QString{"Could not update metadata due to invalid modification time for %1: %2"}.arg(path).arg(modtime)}; - } - - const auto info = replacesPath.isEmpty() ? findPlaceholderInfo(path) - : findPlaceholderInfo(replacesPath); - if (!info) { - return { "Can't update non existing placeholder info" }; - } - - const auto previousPinState = cfPinStateToPinState(info->PinState); - const auto fileIdentity = QString::fromUtf8(fileId).toStdWString(); - const auto fileIdentitySize = (fileIdentity.length() + 1) * sizeof(wchar_t); - - CF_FS_METADATA metadata; - metadata.FileSize.QuadPart = size; - OCC::Utility::UnixTimeToLargeIntegerFiletime(modtime, &metadata.BasicInfo.CreationTime); - OCC::Utility::UnixTimeToLargeIntegerFiletime(modtime, &metadata.BasicInfo.LastWriteTime); - OCC::Utility::UnixTimeToLargeIntegerFiletime(modtime, &metadata.BasicInfo.LastAccessTime); - OCC::Utility::UnixTimeToLargeIntegerFiletime(modtime, &metadata.BasicInfo.ChangeTime); - metadata.BasicInfo.FileAttributes = 0; - - const qint64 result = CfUpdatePlaceholder(handleForPath(path).get(), &metadata, - fileIdentity.data(), sizeToDWORD(fileIdentitySize), - nullptr, 0, CF_UPDATE_FLAG_MARK_IN_SYNC, nullptr, nullptr); - - if (result != S_OK) { - qCWarning(lcCfApiWrapper) << "Couldn't update placeholder info for" << path << ":" << QString::fromWCharArray(_com_error(result).ErrorMessage()) << replacesPath; - return { "Couldn't update placeholder info" }; - } - - // Pin state tends to be lost on updates, so restore it every time - if (!setPinState(path, previousPinState, NoRecurse)) { - return { "Couldn't restore pin state" }; - } - - return OCC::Vfs::ConvertToPlaceholderResult::Ok; + return updatePlaceholderState(path, modtime, size, fileId, replacesPath, CfApiUpdateMetadataType::AllMetadata); } OCC::Result OCC::CfApiWrapper::dehydratePlaceholder(const QString &path, time_t modtime, qint64 size, const QByteArray &fileId) @@ -862,3 +872,8 @@ OCC::Result OCC::CfApiWrapper::co return stateResult; } } + +OCC::Result OCC::CfApiWrapper::updatePlaceholderMarkInSync(const QString &path, const QByteArray &fileId, const QString &replacesPath) +{ + return updatePlaceholderState(path, {}, {}, fileId, replacesPath, CfApiUpdateMetadataType::OnlyBasicMetadata); +} diff --git a/src/libsync/vfs/cfapi/cfapiwrapper.h b/src/libsync/vfs/cfapi/cfapiwrapper.h index 10cb51aaa82bb..94ebff914cbe6 100644 --- a/src/libsync/vfs/cfapi/cfapiwrapper.h +++ b/src/libsync/vfs/cfapi/cfapiwrapper.h @@ -97,6 +97,7 @@ NEXTCLOUD_CFAPI_EXPORT Result createPlaceholderInfo(const QString NEXTCLOUD_CFAPI_EXPORT Result updatePlaceholderInfo(const QString &path, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath = QString()); NEXTCLOUD_CFAPI_EXPORT Result convertToPlaceholder(const QString &path, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath); NEXTCLOUD_CFAPI_EXPORT Result dehydratePlaceholder(const QString &path, time_t modtime, qint64 size, const QByteArray &fileId); +NEXTCLOUD_CFAPI_EXPORT Result updatePlaceholderMarkInSync(const QString &path, const QByteArray &fileId, const QString &replacesPath = QString()); } diff --git a/src/libsync/vfs/cfapi/vfs_cfapi.cpp b/src/libsync/vfs/cfapi/vfs_cfapi.cpp index 595cc52159185..e7905fe6ca7c0 100644 --- a/src/libsync/vfs/cfapi/vfs_cfapi.cpp +++ b/src/libsync/vfs/cfapi/vfs_cfapi.cpp @@ -222,7 +222,7 @@ Result VfsCfApi::dehydratePlaceholder(const SyncFileItem &item) } } -Result VfsCfApi::convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &replacesFile) +Result VfsCfApi::convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &replacesFile, UpdateMetadataTypes updateType) { const auto localPath = QDir::toNativeSeparators(filename); @@ -238,7 +238,11 @@ Result VfsCfApi::convertToPlaceholder( const auto replacesPath = QDir::toNativeSeparators(replacesFile); if (cfapi::findPlaceholderInfo(localPath)) { - return cfapi::updatePlaceholderInfo(localPath, item._modtime, item._size, item._fileId, replacesPath); + if (updateType & Vfs::UpdateMetadataType::FileMetadata) { + return cfapi::updatePlaceholderInfo(localPath, item._modtime, item._size, item._fileId, replacesPath); + } else { + return cfapi::updatePlaceholderMarkInSync(localPath, item._fileId, replacesPath); + } } else { return cfapi::convertToPlaceholder(localPath, item._modtime, item._size, item._fileId, replacesPath); } diff --git a/src/libsync/vfs/cfapi/vfs_cfapi.h b/src/libsync/vfs/cfapi/vfs_cfapi.h index b675ae389f0e7..ce0d97ea0ccb2 100644 --- a/src/libsync/vfs/cfapi/vfs_cfapi.h +++ b/src/libsync/vfs/cfapi/vfs_cfapi.h @@ -45,7 +45,7 @@ class VfsCfApi : public Vfs Result createPlaceholder(const SyncFileItem &item) override; Result dehydratePlaceholder(const SyncFileItem &item) override; - Result convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &replacesFile) override; + Result convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &replacesFile, UpdateMetadataTypes updateType) override; bool needsMetadataUpdate(const SyncFileItem &) override; bool isDehydratedPlaceholder(const QString &filePath) override; diff --git a/src/libsync/vfs/suffix/vfs_suffix.cpp b/src/libsync/vfs/suffix/vfs_suffix.cpp index 6fcb1d2f51da2..f4d5e9a05d72b 100644 --- a/src/libsync/vfs/suffix/vfs_suffix.cpp +++ b/src/libsync/vfs/suffix/vfs_suffix.cpp @@ -138,7 +138,7 @@ Result VfsSuffix::dehydratePlaceholder(const SyncFileItem &item) return {}; } -Result VfsSuffix::convertToPlaceholder(const QString &, const SyncFileItem &, const QString &) +Result VfsSuffix::convertToPlaceholder(const QString &, const SyncFileItem &, const QString &, UpdateMetadataTypes) { // Nothing necessary return Vfs::ConvertToPlaceholderResult::Ok; diff --git a/src/libsync/vfs/suffix/vfs_suffix.h b/src/libsync/vfs/suffix/vfs_suffix.h index 6169290ba3224..3164802d9c83d 100644 --- a/src/libsync/vfs/suffix/vfs_suffix.h +++ b/src/libsync/vfs/suffix/vfs_suffix.h @@ -42,7 +42,7 @@ class VfsSuffix : public Vfs Result createPlaceholder(const SyncFileItem &item) override; Result dehydratePlaceholder(const SyncFileItem &item) override; - Result convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &) override; + Result convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &, UpdateMetadataTypes updateType) override; bool needsMetadataUpdate(const SyncFileItem &) override { return false; } bool isDehydratedPlaceholder(const QString &filePath) override; diff --git a/src/libsync/vfs/xattr/vfs_xattr.cpp b/src/libsync/vfs/xattr/vfs_xattr.cpp index 4300f6d30ad24..f6ba09f1e365d 100644 --- a/src/libsync/vfs/xattr/vfs_xattr.cpp +++ b/src/libsync/vfs/xattr/vfs_xattr.cpp @@ -122,7 +122,10 @@ Result VfsXAttr::dehydratePlaceholder(const SyncFileItem &item) return {}; } -Result VfsXAttr::convertToPlaceholder(const QString &, const SyncFileItem &, const QString &) +Result VfsXAttr::convertToPlaceholder(const QString &, + const SyncFileItem &, + const QString &, + UpdateMetadataTypes) { // Nothing necessary return {ConvertToPlaceholderResult::Ok}; diff --git a/src/libsync/vfs/xattr/vfs_xattr.h b/src/libsync/vfs/xattr/vfs_xattr.h index 118d4d2864f9b..b9fc9548c4707 100644 --- a/src/libsync/vfs/xattr/vfs_xattr.h +++ b/src/libsync/vfs/xattr/vfs_xattr.h @@ -42,7 +42,10 @@ class VfsXAttr : public Vfs Result createPlaceholder(const SyncFileItem &item) override; Result dehydratePlaceholder(const SyncFileItem &item) override; - Result convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &replacesFile) override; + Result convertToPlaceholder(const QString &filename, + const SyncFileItem &item, + const QString &replacesFile, + UpdateMetadataTypes updateType) override; bool needsMetadataUpdate(const SyncFileItem &item) override; bool isDehydratedPlaceholder(const QString &filePath) override; From e33d2044ed4d32883567eae4e07cf588f33854d0 Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Mon, 20 Nov 2023 12:17:35 +0100 Subject: [PATCH 3/3] extend log to get information about mtime modifications by the client Signed-off-by: Matthieu Gallien --- src/gui/folderwatcher.cpp | 1 + src/libsync/owncloudpropagator.cpp | 1 + src/libsync/propagatedownload.cpp | 2 ++ src/libsync/vfs/cfapi/cfapiwrapper.cpp | 1 + src/libsync/vfs/suffix/vfs_suffix.cpp | 2 ++ src/libsync/vfs/xattr/vfs_xattr.cpp | 2 ++ 6 files changed, 9 insertions(+) diff --git a/src/gui/folderwatcher.cpp b/src/gui/folderwatcher.cpp index c08d544729839..07436463a81ab 100644 --- a/src/gui/folderwatcher.cpp +++ b/src/gui/folderwatcher.cpp @@ -146,6 +146,7 @@ void FolderWatcher::startNotificationTestWhenReady() auto path = _testNotificationPath; if (QFile::exists(path)) { auto mtime = FileSystem::getModTime(path); + qCDebug(lcFolderWatcher()) << "setModTime" << path << (mtime + 1); FileSystem::setModTime(path, mtime + 1); } else { QFile f(path); diff --git a/src/libsync/owncloudpropagator.cpp b/src/libsync/owncloudpropagator.cpp index b2a058088c303..4745b4f846fbe 100644 --- a/src/libsync/owncloudpropagator.cpp +++ b/src/libsync/owncloudpropagator.cpp @@ -1378,6 +1378,7 @@ void PropagateDirectory::slotSubJobsFinished(SyncFileItem::Status status) qCWarning(lcDirectory) << "Error writing to the database for file" << _item->_file; } + qCDebug(lcPropagator()) << "setModTime" << propagator()->fullLocalPath(_item->destination()) << _item->_modtime; FileSystem::setModTime(propagator()->fullLocalPath(_item->destination()), _item->_modtime); } diff --git a/src/libsync/propagatedownload.cpp b/src/libsync/propagatedownload.cpp index cdc4d17e97ab2..6d7d5e2ebee0b 100644 --- a/src/libsync/propagatedownload.cpp +++ b/src/libsync/propagatedownload.cpp @@ -606,6 +606,7 @@ void PropagateDownloadFile::conflictChecksumComputed(const QByteArray &checksumT } if (_item->_modtime != _item->_previousModtime) { Q_ASSERT(_item->_modtime > 0); + qCDebug(lcPropagateDownload()) << "setModTime" << fn << _item->_modtime; FileSystem::setModTime(fn, _item->_modtime); emit propagator()->touchedFile(fn); } @@ -1162,6 +1163,7 @@ void PropagateDownloadFile::downloadFinished() if (_item->_modtime <= 0) { qCWarning(lcPropagateDownload()) << "invalid modified time" << _item->_file << _item->_modtime; } + qCDebug(lcPropagateDownload()) << "setModTime" << _tmpFile.fileName() << _item->_modtime; FileSystem::setModTime(_tmpFile.fileName(), _item->_modtime); // We need to fetch the time again because some file systems such as FAT have worse than a second // Accuracy, and we really need the time from the file system. (#3103) diff --git a/src/libsync/vfs/cfapi/cfapiwrapper.cpp b/src/libsync/vfs/cfapi/cfapiwrapper.cpp index bd445042dcae5..12c4f740238a5 100644 --- a/src/libsync/vfs/cfapi/cfapiwrapper.cpp +++ b/src/libsync/vfs/cfapi/cfapiwrapper.cpp @@ -779,6 +779,7 @@ OCC::Result OCC::CfApiWrapper::createPlaceholderInfo(const QStrin cloudEntry.FsMetadata.FileSize.QuadPart = 0; } + qCDebug(lcCfApiWrapper) << "CfCreatePlaceholders" << path << modtime; const qint64 result = CfCreatePlaceholders(localBasePath.data(), &cloudEntry, 1, CF_CREATE_FLAG_NONE, nullptr); if (result != S_OK) { qCWarning(lcCfApiWrapper) << "Couldn't create placeholder info for" << path << ":" << QString::fromWCharArray(_com_error(result).ErrorMessage()); diff --git a/src/libsync/vfs/suffix/vfs_suffix.cpp b/src/libsync/vfs/suffix/vfs_suffix.cpp index f4d5e9a05d72b..d82422787e279 100644 --- a/src/libsync/vfs/suffix/vfs_suffix.cpp +++ b/src/libsync/vfs/suffix/vfs_suffix.cpp @@ -80,6 +80,7 @@ Result VfsSuffix::updateMetadata(const QString &filePath, time_t return {tr("Error updating metadata due to invalid modification time")}; } + qCDebug(lcVfsSuffix()) << "setModTime" << filePath << modtime; FileSystem::setModTime(filePath, modtime); return {}; } @@ -108,6 +109,7 @@ Result VfsSuffix::createPlaceholder(const SyncFileItem &item) file.write(" "); file.close(); + qCDebug(lcVfsSuffix()) << "setModTime" << fn << item._modtime; FileSystem::setModTime(fn, item._modtime); return {}; } diff --git a/src/libsync/vfs/xattr/vfs_xattr.cpp b/src/libsync/vfs/xattr/vfs_xattr.cpp index f6ba09f1e365d..cf553eb37c5fd 100644 --- a/src/libsync/vfs/xattr/vfs_xattr.cpp +++ b/src/libsync/vfs/xattr/vfs_xattr.cpp @@ -75,6 +75,7 @@ Result VfsXAttr::updateMetadata(const QString &filePath, time_t m return {tr("Error updating metadata due to invalid modification time")}; } + qCDebug(lcVfsXAttr()) << "setModTime" << filePath << modtime; FileSystem::setModTime(filePath, modtime); return {}; } @@ -98,6 +99,7 @@ Result VfsXAttr::createPlaceholder(const SyncFileItem &item) file.write(" "); file.close(); + qCDebug(lcVfsXAttr()) << "setModTime" << path << item._modtime; FileSystem::setModTime(path, item._modtime); return xattr::addNextcloudPlaceholderAttributes(path); }