Skip to content

Commit

Permalink
if a virtual file change but bothing changed: set it as in sync
Browse files Browse the repository at this point in the history
Signed-off-by: Matthieu Gallien <[email protected]>
  • Loading branch information
mgallien committed Apr 12, 2024
1 parent d6ed678 commit d023c0b
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 4 deletions.
8 changes: 7 additions & 1 deletion src/common/vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,11 @@ class OCSYNC_EXPORT Vfs : public QObject
* If the remote metadata changes, the local placeholder's metadata should possibly
* change as well.
*/
Q_REQUIRED_RESULT virtual Result<void, QString> updateMetadata(const QString &filePath, time_t modtime, qint64 size, const QByteArray &fileId) = 0;
[[nodiscard]] virtual Result<void, QString> updateMetadata(const QString &filePath, time_t modtime, qint64 size, const QByteArray &fileId) = 0;

[[nodiscard]] virtual Result<Vfs::ConvertToPlaceholderResult, QString> updatePlaceholderMarkInSync(const QString &filePath, const QByteArray &fileId) = 0;

[[nodiscard]] virtual bool isPlaceHolderInSync(const QString &filePath) const = 0;

/// Create a new dehydrated placeholder. Called from PropagateDownload.
Q_REQUIRED_RESULT virtual Result<void, QString> createPlaceholder(const SyncFileItem &item) = 0;
Expand Down Expand Up @@ -325,6 +329,8 @@ class OCSYNC_EXPORT VfsOff : public Vfs
[[nodiscard]] bool isHydrating() const override { return false; }

Result<void, QString> updateMetadata(const QString &, time_t, qint64, const QByteArray &) override { return {}; }
Result<Vfs::ConvertToPlaceholderResult, QString> updatePlaceholderMarkInSync(const QString &filePath, const QByteArray &fileId) override {return {QString{}};}
bool isPlaceHolderInSync(const QString &filePath) const override { Q_UNUSED(filePath) return true; }
Result<void, QString> createPlaceholder(const SyncFileItem &) override { return {}; }
Result<void, QString> dehydratePlaceholder(const SyncFileItem &) override { return {}; }
Result<ConvertToPlaceholderResult, QString> convertToPlaceholder(const QString &, const SyncFileItem &, const QString &, const UpdateMetadataTypes) override { return ConvertToPlaceholderResult::Ok; }
Expand Down
1 change: 1 addition & 0 deletions src/csync/csync.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ enum SyncInstructions {
CSYNC_INSTRUCTION_UPDATE_METADATA = 1 << 10, /* If the etag has been updated and need to be writen to the db,
but without any propagation (UPDATE|RECONCILE) */
CSYNC_INSTRUCTION_CASE_CLASH_CONFLICT = 1 << 12, /* The file need to be downloaded because it is a case clash conflict (RECONCILE) */
CSYNC_INSTRUCTION_UPDATE_VFS_METADATA = 1 << 13, /* vfs item metadata are out of sync and we need to tell operating system about it */
};

Q_ENUM_NS(SyncInstructions)
Expand Down
26 changes: 23 additions & 3 deletions src/gui/folder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -620,11 +620,31 @@ void Folder::slotWatchedPathChanged(const QString &path, ChangeReason reason)
&& !FileSystem::fileChanged(path, record._fileSize, record._modtime) && _vfs) {
spurious = true;

if (auto pinState = _vfs->pinState(relativePath.toString())) {
if (*pinState == PinState::AlwaysLocal && record.isVirtualFile())
const auto fileAvailability = _vfs->availability(relativePath.toString(), Vfs::AvailabilityRecursivity::NotRecursiveAvailability);

qCInfo(lcFolder) << path
<< "file size:" << record._fileSize << FileSystem::getSize(path)
<< "file modtime:" << record._modtime << FileSystem::getModTime(path)
<< "pin state:" << (*_vfs->pinState(relativePath.toString()))
<< "virtual file:" << (fileAvailability && *fileAvailability == VfsItemAvailability::OnlineOnly ? "is virtual file" : "is plain old file");

if (const auto pinState = _vfs->pinState(relativePath.toString())) {
if (*pinState == PinState::AlwaysLocal && fileAvailability && *fileAvailability == VfsItemAvailability::OnlineOnly) {
spurious = false;
}
if (*pinState == PinState::OnlineOnly && (!fileAvailability || *fileAvailability != VfsItemAvailability::OnlineOnly)) {
spurious = false;
if (*pinState == PinState::OnlineOnly && record.isFile())
}
if (*pinState == PinState::OnlineOnly && fileAvailability && *fileAvailability == VfsItemAvailability::OnlineOnly) {
qCInfo(lcFolder) << "Not a spurious notification for file" << relativePath;
const auto result = _vfs->updateMetadata(path, FileSystem::getModTime(path), FileSystem::getSize(path), record._fileId);
Q_UNUSED(result)
spurious = false;
}
if (!_vfs->isPlaceHolderInSync(path)) {
qCInfo(lcFolder) << "Not a spurious notification for virtual file not in synced" << path;
spurious = false;
}
} else {
spurious = false;
}
Expand Down
6 changes: 6 additions & 0 deletions src/libsync/discovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1675,6 +1675,12 @@ void ProcessDirectoryJob::processFileFinalize(
}
}

if (_discoveryData->_syncOptions._vfs &&
item->_type == CSyncEnums::ItemTypeFile &&
_discoveryData->_syncOptions._vfs->isPlaceHolderInSync(path._local)) {
item->_instruction = CSyncEnums::CSYNC_INSTRUCTION_UPDATE_VFS_METADATA;
}

if (path._original != path._target && (item->_instruction == CSYNC_INSTRUCTION_UPDATE_METADATA || item->_instruction == CSYNC_INSTRUCTION_NONE)) {
ASSERT(_dirItem && _dirItem->_instruction == CSYNC_INSTRUCTION_RENAME);
// This is because otherwise subitems are not updated! (ideally renaming a directory could
Expand Down
10 changes: 10 additions & 0 deletions src/libsync/vfs/cfapi/cfapiwrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -900,3 +900,13 @@ OCC::Result<OCC::Vfs::ConvertToPlaceholderResult, QString> OCC::CfApiWrapper::up
{
return updatePlaceholderState(path, {}, {}, fileId, replacesPath, CfApiUpdateMetadataType::OnlyBasicMetadata);
}

bool OCC::CfApiWrapper::isPlaceHolderInSync(const QString &filePath)
{
const auto originalInfo = findPlaceholderInfo(filePath);
if (originalInfo) {
return originalInfo->InSyncState == CF_IN_SYNC_STATE_NOT_IN_SYNC;
} else {
return true;
}
}
1 change: 1 addition & 0 deletions src/libsync/vfs/cfapi/cfapiwrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ NEXTCLOUD_CFAPI_EXPORT Result<OCC::Vfs::ConvertToPlaceholderResult, QString> upd
NEXTCLOUD_CFAPI_EXPORT Result<OCC::Vfs::ConvertToPlaceholderResult, QString> convertToPlaceholder(const QString &path, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath);
NEXTCLOUD_CFAPI_EXPORT Result<OCC::Vfs::ConvertToPlaceholderResult, QString> dehydratePlaceholder(const QString &path, time_t modtime, qint64 size, const QByteArray &fileId);
NEXTCLOUD_CFAPI_EXPORT Result<OCC::Vfs::ConvertToPlaceholderResult, QString> updatePlaceholderMarkInSync(const QString &path, const QByteArray &fileId, const QString &replacesPath = QString());
NEXTCLOUD_CFAPI_EXPORT bool isPlaceHolderInSync(const QString &filePath);

}

Expand Down
10 changes: 10 additions & 0 deletions src/libsync/vfs/cfapi/vfs_cfapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,16 @@ Result<void, QString> VfsCfApi::updateMetadata(const QString &filePath, time_t m
}
}

Result<Vfs::ConvertToPlaceholderResult, QString> VfsCfApi::updatePlaceholderMarkInSync(const QString &filePath, const QByteArray &fileId)
{
return cfapi::updatePlaceholderMarkInSync(filePath, fileId, {});
}

bool VfsCfApi::isPlaceHolderInSync(const QString &filePath) const
{
return cfapi::isPlaceHolderInSync(filePath);
}

Result<void, QString> VfsCfApi::createPlaceholder(const SyncFileItem &item)
{
Q_ASSERT(params().filesystemPath.endsWith('/'));
Expand Down
4 changes: 4 additions & 0 deletions src/libsync/vfs/cfapi/vfs_cfapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ class VfsCfApi : public Vfs

Result<void, QString> updateMetadata(const QString &filePath, time_t modtime, qint64 size, const QByteArray &fileId) override;

Result<Vfs::ConvertToPlaceholderResult, QString> updatePlaceholderMarkInSync(const QString &filePath, const QByteArray &fileId) override;

bool isPlaceHolderInSync(const QString &filePath) const override;

Result<void, QString> createPlaceholder(const SyncFileItem &item) override;
Result<void, QString> dehydratePlaceholder(const SyncFileItem &item) override;
Result<Vfs::ConvertToPlaceholderResult, QString> convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &replacesFile, UpdateMetadataTypes updateType) override;
Expand Down
2 changes: 2 additions & 0 deletions src/libsync/vfs/suffix/vfs_suffix.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class VfsSuffix : public Vfs
[[nodiscard]] bool isHydrating() const override;

Result<void, QString> updateMetadata(const QString &filePath, time_t modtime, qint64 size, const QByteArray &fileId) override;
Result<Vfs::ConvertToPlaceholderResult, QString> updatePlaceholderMarkInSync(const QString &filePath, const QByteArray &fileId) override {return {QString{}};}
bool isPlaceHolderInSync(const QString &filePath) const override { Q_UNUSED(filePath) return true; }

Result<void, QString> createPlaceholder(const SyncFileItem &item) override;
Result<void, QString> dehydratePlaceholder(const SyncFileItem &item) override;
Expand Down

0 comments on commit d023c0b

Please sign in to comment.