From: Christian Kamm Date: Mon, 21 Jan 2019 10:22:40 +0000 (+0100) Subject: Vfs: Make files that end up in db placeholders X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~12^2~21^2~468^2~314 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=31394f14b57d687c965865014d391eb27fad3660;p=nextcloud-desktop.git Vfs: Make files that end up in db placeholders Since 'placeholder' just means that it's an item of the special type that the vfs plugin can deal with - no matter whether hydrated or dehydrated - all done items should become placeholders. Even directories. Now every file that passes through updateMetadata() will be converted to a placeholder if necessary. --- diff --git a/src/common/vfs.h b/src/common/vfs.h index 727c06273..a358619cb 100644 --- a/src/common/vfs.h +++ b/src/common/vfs.h @@ -31,7 +31,6 @@ typedef QSharedPointer AccountPtr; class SyncJournalDb; class VfsPrivate; class SyncFileItem; -typedef QSharedPointer SyncFileItemPtr; /** Collection of parameters for initializing a Vfs instance. */ struct OCSYNC_EXPORT VfsSetupParams @@ -129,15 +128,18 @@ public: virtual bool updateMetadata(const QString &filePath, time_t modtime, quint64 size, const QByteArray &fileId, QString *error) = 0; /// Create a new dehydrated placeholder. Called from PropagateDownload. - virtual void createPlaceholder(const QString &syncFolder, const SyncFileItemPtr &item) = 0; + virtual void createPlaceholder(const QString &syncFolder, const SyncFileItem &item) = 0; /** Convert a new file to a hydrated placeholder. * * Some VFS integrations expect that every file, including those that have all * the remote data, are "placeholders". This function is called by PropagateDownload * to convert newly downloaded, fully hydrated files into placeholders. + * + * Implementations must make sure that calling this function on a file that already + * is a placeholder is acceptable. */ - virtual void convertToPlaceholder(const QString &filename, const SyncFileItemPtr &item) = 0; + virtual void convertToPlaceholder(const QString &filename, const SyncFileItem &item) = 0; /// Determine whether the file at the given absolute path is a dehydrated placeholder. virtual bool isDehydratedPlaceholder(const QString &filePath) = 0; @@ -180,8 +182,8 @@ public: bool isHydrating() const override { return false; } bool updateMetadata(const QString &, time_t, quint64, const QByteArray &, QString *) override { return true; } - void createPlaceholder(const QString &, const SyncFileItemPtr &) override {} - void convertToPlaceholder(const QString &, const SyncFileItemPtr &) override {} + void createPlaceholder(const QString &, const SyncFileItem &) override {} + void convertToPlaceholder(const QString &, const SyncFileItem &) override {} bool isDehydratedPlaceholder(const QString &) override { return false; } bool statTypeVirtualFile(csync_file_stat_t *, void *) override { return false; } diff --git a/src/libsync/owncloudpropagator.cpp b/src/libsync/owncloudpropagator.cpp index b6813c4d8..673fa1737 100644 --- a/src/libsync/owncloudpropagator.cpp +++ b/src/libsync/owncloudpropagator.cpp @@ -724,11 +724,17 @@ QString OwncloudPropagator::adjustRenamedPath(const QString &original) const return OCC::adjustRenamedPath(_renamedDirectories, original); } -bool OwncloudPropagator::updateMetadata(const SyncFileItem &item) +bool OwncloudPropagator::updateMetadata(const SyncFileItem &item, const QString &localFolderPath, SyncJournalDb &journal, Vfs &vfs) { - QString fsPath = getFilePath(item.destination()); + QString fsPath = localFolderPath + item.destination(); + vfs.convertToPlaceholder(fsPath, item); auto record = item.toSyncJournalFileRecordWithInode(fsPath); - return _journal->setFileRecord(record); + return journal.setFileRecord(record); +} + +bool OwncloudPropagator::updateMetadata(const SyncFileItem &item) +{ + return updateMetadata(item, _localDir, *_journal, *syncOptions()._vfs); } // ================================================================================ @@ -1019,9 +1025,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 { - // want to do Propagator::updateMetadata() - QString filesystemPath = _localPath + job->_item->_file; - if (!_journal->setFileRecord(job->_item->toSyncJournalFileRecordWithInode(filesystemPath))) { + if (!OwncloudPropagator::updateMetadata(*job->_item, _localPath, *_journal, *_vfs)) { 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 a6b64de2d..211bed5a4 100644 --- a/src/libsync/owncloudpropagator.h +++ b/src/libsync/owncloudpropagator.h @@ -511,8 +511,11 @@ public: * * Typically after a sync operation succeeded. Updates the inode from * the filesystem. + * + * Will also trigger a Vfs::convertToPlaceholder. */ - bool updateMetadata(const SyncFileItem &item); + static bool updateMetadata(const SyncFileItem &item, const QString &localFolderPath, SyncJournalDb &journal, Vfs &vfs); + bool updateMetadata(const SyncFileItem &item); // convenience for the above private slots: @@ -570,15 +573,17 @@ class CleanupPollsJob : public QObject AccountPtr _account; SyncJournalDb *_journal; QString _localPath; + QSharedPointer _vfs; public: explicit CleanupPollsJob(const QVector &pollInfos, AccountPtr account, - SyncJournalDb *journal, const QString &localPath, QObject *parent = nullptr) + SyncJournalDb *journal, const QString &localPath, const QSharedPointer &vfs, QObject *parent = nullptr) : QObject(parent) , _pollInfos(pollInfos) , _account(account) , _journal(journal) , _localPath(localPath) + , _vfs(vfs) { } diff --git a/src/libsync/propagatedownload.cpp b/src/libsync/propagatedownload.cpp index 97592d465..fe0cceac7 100644 --- a/src/libsync/propagatedownload.cpp +++ b/src/libsync/propagatedownload.cpp @@ -440,7 +440,7 @@ void PropagateDownloadFile::startAfterIsEncryptedIsChecked() auto fn = propagator()->getFilePath(_item->_file); qCDebug(lcPropagateDownload) << "creating virtual file" << fn; - vfs->createPlaceholder(propagator()->_localDir, _item); + vfs->createPlaceholder(propagator()->_localDir, *_item); updateMetadata(false); return; } @@ -1005,7 +1005,7 @@ void PropagateDownloadFile::downloadFinished() } // Make the file a hydrated placeholder if possible - propagator()->syncOptions()._vfs->convertToPlaceholder(fn, _item); + propagator()->syncOptions()._vfs->convertToPlaceholder(fn, *_item); FileSystem::setFileHidden(fn, false); diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index a10edb7b2..fc2c30ce3 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -411,7 +411,7 @@ void SyncEngine::startSync() if (!pollInfos.isEmpty()) { qCInfo(lcEngine) << "Finish Poll jobs before starting a sync"; auto *job = new CleanupPollsJob(pollInfos, _account, - _journal, _localPath, this); + _journal, _localPath, _syncOptions._vfs, this); connect(job, &CleanupPollsJob::finished, this, &SyncEngine::startSync); connect(job, &CleanupPollsJob::aborted, this, &SyncEngine::slotCleanPollsJobAborted); job->start(); diff --git a/src/libsync/vfs/suffix/vfs_suffix.cpp b/src/libsync/vfs/suffix/vfs_suffix.cpp index b99f4f2e5..60d753a1b 100644 --- a/src/libsync/vfs/suffix/vfs_suffix.cpp +++ b/src/libsync/vfs/suffix/vfs_suffix.cpp @@ -67,18 +67,18 @@ bool VfsSuffix::updateMetadata(const QString &filePath, time_t modtime, quint64, return true; } -void VfsSuffix::createPlaceholder(const QString &syncFolder, const SyncFileItemPtr &item) +void VfsSuffix::createPlaceholder(const QString &syncFolder, const SyncFileItem &item) { // The concrete shape of the placeholder is also used in isDehydratedPlaceholder() below - QString fn = syncFolder + item->_file; + QString fn = syncFolder + item._file; QFile file(fn); file.open(QFile::ReadWrite | QFile::Truncate); file.write(" "); file.close(); - FileSystem::setModTime(fn, item->_modtime); + FileSystem::setModTime(fn, item._modtime); } -void VfsSuffix::convertToPlaceholder(const QString &, const SyncFileItemPtr &) +void VfsSuffix::convertToPlaceholder(const QString &, const SyncFileItem &) { // Nothing necessary } diff --git a/src/libsync/vfs/suffix/vfs_suffix.h b/src/libsync/vfs/suffix/vfs_suffix.h index 6d45fc75c..6c60c530a 100644 --- a/src/libsync/vfs/suffix/vfs_suffix.h +++ b/src/libsync/vfs/suffix/vfs_suffix.h @@ -41,8 +41,8 @@ public: bool updateMetadata(const QString &filePath, time_t modtime, quint64 size, const QByteArray &fileId, QString *error) override; - void createPlaceholder(const QString &syncFolder, const SyncFileItemPtr &item) override; - void convertToPlaceholder(const QString &filename, const SyncFileItemPtr &item) override; + void createPlaceholder(const QString &syncFolder, const SyncFileItem &item) override; + void convertToPlaceholder(const QString &filename, const SyncFileItem &item) override; bool isDehydratedPlaceholder(const QString &filePath) override; bool statTypeVirtualFile(csync_file_stat_t *stat, void *stat_data) override;