Merge pull request #3511 from nextcloud/bugfix/vfsFixes

Improve the error message returned by updateMetadata
This commit is contained in:
Matthieu Gallien 2021-07-06 16:15:26 +02:00 committed by GitHub
commit c1f0716d53
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 115 additions and 58 deletions

View file

@ -898,7 +898,7 @@ qint64 SyncJournalDb::getPHash(const QByteArray &file)
return h; return h;
} }
bool SyncJournalDb::setFileRecord(const SyncJournalFileRecord &_record) Result<void, QString> SyncJournalDb::setFileRecord(const SyncJournalFileRecord &_record)
{ {
SyncJournalFileRecord record = _record; SyncJournalFileRecord record = _record;
QMutexLocker locker(&_mutex); QMutexLocker locker(&_mutex);
@ -940,7 +940,7 @@ bool SyncJournalDb::setFileRecord(const SyncJournalFileRecord &_record)
"INSERT OR REPLACE INTO metadata " "INSERT OR REPLACE INTO metadata "
"(phash, pathlen, path, inode, uid, gid, mode, modtime, type, md5, fileid, remotePerm, filesize, ignoredChildrenRemote, contentChecksum, contentChecksumTypeId, e2eMangledName, isE2eEncrypted) " "(phash, pathlen, path, inode, uid, gid, mode, modtime, type, md5, fileid, remotePerm, filesize, ignoredChildrenRemote, contentChecksum, contentChecksumTypeId, e2eMangledName, isE2eEncrypted) "
"VALUES (?1 , ?2, ?3 , ?4 , ?5 , ?6 , ?7, ?8 , ?9 , ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18);"), _db)) { "VALUES (?1 , ?2, ?3 , ?4 , ?5 , ?6 , ?7, ?8 , ?9 , ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18);"), _db)) {
return false; return _setFileRecordQuery.error();
} }
_setFileRecordQuery.bindValue(1, phash); _setFileRecordQuery.bindValue(1, phash);
@ -963,16 +963,16 @@ bool SyncJournalDb::setFileRecord(const SyncJournalFileRecord &_record)
_setFileRecordQuery.bindValue(18, record._isE2eEncrypted); _setFileRecordQuery.bindValue(18, record._isE2eEncrypted);
if (!_setFileRecordQuery.exec()) { if (!_setFileRecordQuery.exec()) {
return false; return _setFileRecordQuery.error();
} }
// Can't be true anymore. // Can't be true anymore.
_metadataTableIsEmpty = false; _metadataTableIsEmpty = false;
return true; return {};
} else { } else {
qCWarning(lcDb) << "Failed to connect database."; qCWarning(lcDb) << "Failed to connect database.";
return false; // checkConnect failed. return tr("Failed to connect database."); // checkConnect failed.
} }
} }

View file

@ -65,7 +65,7 @@ public:
bool getFileRecordsByFileId(const QByteArray &fileId, const std::function<void(const SyncJournalFileRecord &)> &rowCallback); bool getFileRecordsByFileId(const QByteArray &fileId, const std::function<void(const SyncJournalFileRecord &)> &rowCallback);
bool getFilesBelowPath(const QByteArray &path, const std::function<void(const SyncJournalFileRecord&)> &rowCallback); bool getFilesBelowPath(const QByteArray &path, const std::function<void(const SyncJournalFileRecord&)> &rowCallback);
bool listFilesInPath(const QByteArray &path, const std::function<void(const SyncJournalFileRecord&)> &rowCallback); bool listFilesInPath(const QByteArray &path, const std::function<void(const SyncJournalFileRecord&)> &rowCallback);
bool setFileRecord(const SyncJournalFileRecord &record); Result<void, QString> setFileRecord(const SyncJournalFileRecord &record);
void keyValueStoreSet(const QString &key, QVariant value); void keyValueStoreSet(const QString &key, QVariant value);
qint64 keyValueStoreGetInt(const QString &key, qint64 defaultValue); qint64 keyValueStoreGetInt(const QString &key, qint64 defaultValue);

View file

@ -104,6 +104,13 @@ public:
XAttr, XAttr,
}; };
Q_ENUM(Mode) Q_ENUM(Mode)
enum class ConvertToPlaceholderResult {
Error,
Ok,
Locked
};
Q_ENUM(ConvertToPlaceholderResult)
static QString modeToString(Mode mode); static QString modeToString(Mode mode);
static Optional<Mode> modeFromString(const QString &str); static Optional<Mode> modeFromString(const QString &str);
@ -197,7 +204,7 @@ public:
* new placeholder shall supersede, for rename-replace actions with new downloads, * new placeholder shall supersede, for rename-replace actions with new downloads,
* for example. * for example.
*/ */
virtual Q_REQUIRED_RESULT Result<void, QString> convertToPlaceholder( virtual Q_REQUIRED_RESULT Result<Vfs::ConvertToPlaceholderResult, QString> convertToPlaceholder(
const QString &filename, const QString &filename,
const SyncFileItem &item, const SyncFileItem &item,
const QString &replacesFile = QString()) = 0; const QString &replacesFile = QString()) = 0;
@ -303,7 +310,7 @@ public:
Result<void, QString> updateMetadata(const QString &, time_t, qint64, const QByteArray &) override { return {}; } Result<void, QString> updateMetadata(const QString &, time_t, qint64, const QByteArray &) override { return {}; }
Result<void, QString> createPlaceholder(const SyncFileItem &) override { return {}; } Result<void, QString> createPlaceholder(const SyncFileItem &) override { return {}; }
Result<void, QString> dehydratePlaceholder(const SyncFileItem &) override { return {}; } Result<void, QString> dehydratePlaceholder(const SyncFileItem &) override { return {}; }
Result<void, QString> convertToPlaceholder(const QString &, const SyncFileItem &, const QString &) override { return {}; } Result<ConvertToPlaceholderResult, QString> convertToPlaceholder(const QString &, const SyncFileItem &, const QString &) override { return ConvertToPlaceholderResult::Ok; }
bool needsMetadataUpdate(const SyncFileItem &) override { return false; } bool needsMetadataUpdate(const SyncFileItem &) override { return false; }
bool isDehydratedPlaceholder(const QString &) override { return false; } bool isDehydratedPlaceholder(const QString &) override { return false; }

View file

@ -756,19 +756,27 @@ QString OwncloudPropagator::adjustRenamedPath(const QString &original) const
return OCC::adjustRenamedPath(_renamedDirectories, original); return OCC::adjustRenamedPath(_renamedDirectories, original);
} }
bool OwncloudPropagator::updateMetadata(const SyncFileItem &item, const QString &localFolderPath, SyncJournalDb &journal, Vfs &vfs) Result<Vfs::ConvertToPlaceholderResult, QString> OwncloudPropagator::updateMetadata(const SyncFileItem &item)
{ {
QString fsPath = localFolderPath + item.destination(); return OwncloudPropagator::staticUpdateMetadata(item, _localDir, syncOptions()._vfs.data(), _journal);
if (!vfs.convertToPlaceholder(fsPath, item)) {
return false;
}
auto record = item.toSyncJournalFileRecordWithInode(fsPath);
return journal.setFileRecord(record);
} }
bool OwncloudPropagator::updateMetadata(const SyncFileItem &item) Result<Vfs::ConvertToPlaceholderResult, QString> OwncloudPropagator::staticUpdateMetadata(const SyncFileItem &item, const QString localDir,
Vfs *vfs, SyncJournalDb *const journal)
{ {
return updateMetadata(item, _localDir, *_journal, *syncOptions()._vfs); const QString fsPath = localDir + item.destination();
const auto result = vfs->convertToPlaceholder(fsPath, item);
if (!result) {
return result.error();
} else if (*result == Vfs::ConvertToPlaceholderResult::Locked) {
return Vfs::ConvertToPlaceholderResult::Locked;
}
auto record = item.toSyncJournalFileRecordWithInode(fsPath);
const auto dBresult = journal->setFileRecord(record);
if (!dBresult) {
return dBresult.error();
}
return Vfs::ConvertToPlaceholderResult::Ok;
} }
// ================================================================================ // ================================================================================
@ -1011,10 +1019,14 @@ void PropagateDirectory::slotSubJobsFinished(SyncFileItem::Status status)
if (_item->_instruction == CSYNC_INSTRUCTION_RENAME if (_item->_instruction == CSYNC_INSTRUCTION_RENAME
|| _item->_instruction == CSYNC_INSTRUCTION_NEW || _item->_instruction == CSYNC_INSTRUCTION_NEW
|| _item->_instruction == CSYNC_INSTRUCTION_UPDATE_METADATA) { || _item->_instruction == CSYNC_INSTRUCTION_UPDATE_METADATA) {
if (!propagator()->updateMetadata(*_item)) { const auto result = propagator()->updateMetadata(*_item);
if (!result) {
status = _item->_status = SyncFileItem::FatalError; status = _item->_status = SyncFileItem::FatalError;
_item->_errorString = tr("Error writing metadata to the database"); _item->_errorString = tr("Error updating metadata: %1").arg(result.error());
qCWarning(lcDirectory) << "Error writing to the database for file" << _item->_file; qCWarning(lcDirectory) << "Error writing to the database for file" << _item->_file << "with" << result.error();
} else if (*result == Vfs::ConvertToPlaceholderResult::Locked) {
_item->_status = SyncFileItem::SoftError;
_item->_errorString = tr("File is currently in use");
} }
} }
} }
@ -1141,7 +1153,7 @@ void CleanupPollsJob::slotPollFinished()
} else if (job->_item->_status != SyncFileItem::Success) { } else if (job->_item->_status != SyncFileItem::Success) {
qCWarning(lcCleanupPolls) << "There was an error with file " << job->_item->_file << job->_item->_errorString; qCWarning(lcCleanupPolls) << "There was an error with file " << job->_item->_file << job->_item->_errorString;
} else { } else {
if (!OwncloudPropagator::updateMetadata(*job->_item, _localPath, *_journal, *_vfs)) { if (!OwncloudPropagator::staticUpdateMetadata(*job->_item, _localPath, _vfs.data(), _journal)) {
qCWarning(lcCleanupPolls) << "database error"; qCWarning(lcCleanupPolls) << "database error";
job->_item->_status = SyncFileItem::FatalError; job->_item->_status = SyncFileItem::FatalError;
job->_item->_errorString = tr("Error writing metadata to the database"); job->_item->_errorString = tr("Error writing metadata to the database");

View file

@ -560,8 +560,17 @@ public:
* *
* Will also trigger a Vfs::convertToPlaceholder. * Will also trigger a Vfs::convertToPlaceholder.
*/ */
static bool updateMetadata(const SyncFileItem &item, const QString &localFolderPath, SyncJournalDb &journal, Vfs &vfs); Result<Vfs::ConvertToPlaceholderResult, QString> updateMetadata(const SyncFileItem &item);
bool updateMetadata(const SyncFileItem &item); // convenience for the above
/** Update the database for an item.
*
* Typically after a sync operation succeeded. Updates the inode from
* the filesystem.
*
* Will also trigger a Vfs::convertToPlaceholder.
*/
static Result<Vfs::ConvertToPlaceholderResult, QString> staticUpdateMetadata(const SyncFileItem &item, const QString localDir,
Vfs *vfs, SyncJournalDb * const journal);
private slots: private slots:
@ -626,8 +635,8 @@ class CleanupPollsJob : public QObject
QSharedPointer<Vfs> _vfs; QSharedPointer<Vfs> _vfs;
public: public:
explicit CleanupPollsJob(const QVector<SyncJournalDb::PollInfo> &pollInfos, AccountPtr account, explicit CleanupPollsJob(const QVector<SyncJournalDb::PollInfo> &pollInfos, AccountPtr account, SyncJournalDb *journal, const QString &localPath,
SyncJournalDb *journal, const QString &localPath, const QSharedPointer<Vfs> &vfs, QObject *parent = nullptr) const QSharedPointer<Vfs> &vfs, QObject *parent = nullptr)
: QObject(parent) : QObject(parent)
, _pollInfos(pollInfos) , _pollInfos(pollInfos)
, _account(account) , _account(account)

View file

@ -1135,10 +1135,13 @@ void PropagateDownloadFile::downloadFinished()
void PropagateDownloadFile::updateMetadata(bool isConflict) void PropagateDownloadFile::updateMetadata(bool isConflict)
{ {
QString fn = propagator()->fullLocalPath(_item->_file); const QString fn = propagator()->fullLocalPath(_item->_file);
const auto result = propagator()->updateMetadata(*_item);
if (!propagator()->updateMetadata(*_item)) { if (!result) {
done(SyncFileItem::FatalError, tr("Error writing metadata to the database")); done(SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error()));
return;
} else if (*result == Vfs::ConvertToPlaceholderResult::Locked) {
done(SyncFileItem::SoftError, tr("The file %1 is currently in use").arg(_item->_file));
return; return;
} }

View file

@ -259,8 +259,12 @@ void PropagateRemoteMkdir::success()
itemCopy._etag.clear(); itemCopy._etag.clear();
// save the file id already so we can detect rename or remove // save the file id already so we can detect rename or remove
if (!propagator()->updateMetadata(itemCopy)) { const auto result = propagator()->updateMetadata(itemCopy);
done(SyncFileItem::FatalError, tr("Error writing metadata to the database")); if (!result) {
done(SyncFileItem::FatalError, tr("Error writing metadata to the database: %1").arg(result.error()));
return;
} else if (*result == Vfs::ConvertToPlaceholderResult::Locked) {
done(SyncFileItem::FatalError, tr("The file %1 is currently in use").arg(_item->_file));
return; return;
} }

View file

@ -252,8 +252,12 @@ void PropagateRemoteMove::finalize()
newItem._size = oldRecord._fileSize; newItem._size = oldRecord._fileSize;
} }
} }
if (!propagator()->updateMetadata(newItem)) { const auto result = propagator()->updateMetadata(newItem);
done(SyncFileItem::FatalError, tr("Error writing metadata to the database")); if (!result) {
done(SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error()));
return;
} else if (*result == Vfs::ConvertToPlaceholderResult::Locked) {
done(SyncFileItem::SoftError, tr("The file %1 is currently in use").arg(newItem._file));
return; return;
} }
if (pinState && *pinState != PinState::Inherited if (pinState && *pinState != PinState::Inherited

View file

@ -765,8 +765,12 @@ void PropagateUploadFileCommon::finalize()
quotaIt.value() -= _fileToUpload._size; quotaIt.value() -= _fileToUpload._size;
// Update the database entry // Update the database entry
if (!propagator()->updateMetadata(*_item)) { const auto result = propagator()->updateMetadata(*_item);
done(SyncFileItem::FatalError, tr("Error writing metadata to the database")); if (!result) {
done(SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error()));
return;
} else if (*result == Vfs::ConvertToPlaceholderResult::Locked) {
done(SyncFileItem::SoftError, tr("The file %1 is currently in use").arg(_item->_file));
return; return;
} }

View file

@ -189,8 +189,12 @@ void PropagateLocalMkdir::startLocalMkdir()
// before the correct etag is stored. // before the correct etag is stored.
SyncFileItem newItem(*_item); SyncFileItem newItem(*_item);
newItem._etag = "_invalid_"; newItem._etag = "_invalid_";
if (!propagator()->updateMetadata(newItem)) { const auto result = propagator()->updateMetadata(newItem);
done(SyncFileItem::FatalError, tr("Error writing metadata to the database")); if (!result) {
done(SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error()));
return;
} else if (*result == Vfs::ConvertToPlaceholderResult::Locked) {
done(SyncFileItem::SoftError, tr("The file %1 is currently in use").arg(newItem._file));
return; return;
} }
propagator()->_journal->commit("localMkdir"); propagator()->_journal->commit("localMkdir");
@ -253,14 +257,18 @@ void PropagateLocalRename::start()
if (oldRecord.isValid()) { if (oldRecord.isValid()) {
newItem._checksumHeader = oldRecord._checksumHeader; newItem._checksumHeader = oldRecord._checksumHeader;
} }
if (!propagator()->updateMetadata(newItem)) { const auto result = propagator()->updateMetadata(newItem);
done(SyncFileItem::FatalError, tr("Error writing metadata to the database")); if (!result) {
done(SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error()));
return;
} else if (*result == Vfs::ConvertToPlaceholderResult::Locked) {
done(SyncFileItem::SoftError, tr("The file %1 is currently in use").arg(newItem._file));
return; return;
} }
} else { } else {
propagator()->_renamedDirectories.insert(oldFile, _item->_renameTarget); propagator()->_renamedDirectories.insert(oldFile, _item->_renameTarget);
if (!PropagateRemoteMove::adjustSelectiveSync(propagator()->_journal, oldFile, _item->_renameTarget)) { if (!PropagateRemoteMove::adjustSelectiveSync(propagator()->_journal, oldFile, _item->_renameTarget)) {
done(SyncFileItem::FatalError, tr("Error writing metadata to the database")); done(SyncFileItem::FatalError, tr("Failed to rename file"));
return; return;
} }
} }

View file

@ -622,14 +622,14 @@ OCC::CfApiWrapper::PlaceHolderInfo OCC::CfApiWrapper::findPlaceholderInfo(const
} }
} }
OCC::Result<void, QString> OCC::CfApiWrapper::setPinState(const FileHandle &handle, OCC::PinStateEnums::PinState state, SetPinRecurseMode mode) OCC::Result<OCC::Vfs::ConvertToPlaceholderResult, QString> OCC::CfApiWrapper::setPinState(const FileHandle &handle, OCC::PinStateEnums::PinState state, SetPinRecurseMode mode)
{ {
const auto cfState = pinStateToCfPinState(state); const auto cfState = pinStateToCfPinState(state);
const auto flags = pinRecurseModeToCfSetPinFlags(mode); const auto flags = pinRecurseModeToCfSetPinFlags(mode);
const qint64 result = CfSetPinState(handle.get(), cfState, flags, nullptr); const qint64 result = CfSetPinState(handle.get(), cfState, flags, nullptr);
if (result == S_OK) { if (result == S_OK) {
return {}; return OCC::Vfs::ConvertToPlaceholderResult::Ok;
} else { } else {
qCWarning(lcCfApiWrapper) << "Couldn't set pin state" << state << "for" << pathForHandle(handle) << "with recurse mode" << mode << ":" << QString::fromWCharArray(_com_error(result).ErrorMessage()); qCWarning(lcCfApiWrapper) << "Couldn't set pin state" << state << "for" << pathForHandle(handle) << "with recurse mode" << mode << ":" << QString::fromWCharArray(_com_error(result).ErrorMessage());
return { "Couldn't set pin state" }; return { "Couldn't set pin state" };
@ -682,7 +682,7 @@ OCC::Result<void, QString> OCC::CfApiWrapper::createPlaceholderInfo(const QStrin
return {}; return {};
} }
OCC::Result<void, QString> OCC::CfApiWrapper::updatePlaceholderInfo(const FileHandle &handle, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath) OCC::Result<OCC::Vfs::ConvertToPlaceholderResult, QString> OCC::CfApiWrapper::updatePlaceholderInfo(const FileHandle &handle, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath)
{ {
Q_ASSERT(handle); Q_ASSERT(handle);
@ -717,10 +717,10 @@ OCC::Result<void, QString> OCC::CfApiWrapper::updatePlaceholderInfo(const FileHa
return { "Couldn't restore pin state" }; return { "Couldn't restore pin state" };
} }
return {}; return OCC::Vfs::ConvertToPlaceholderResult::Ok;
} }
OCC::Result<void, QString> OCC::CfApiWrapper::convertToPlaceholder(const FileHandle &handle, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath) OCC::Result<OCC::Vfs::ConvertToPlaceholderResult, QString> OCC::CfApiWrapper::convertToPlaceholder(const FileHandle &handle, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath)
{ {
Q_UNUSED(modtime); Q_UNUSED(modtime);
Q_UNUSED(size); Q_UNUSED(size);

View file

@ -18,6 +18,7 @@
#include "owncloudlib.h" #include "owncloudlib.h"
#include "common/pinstate.h" #include "common/pinstate.h"
#include "common/result.h" #include "common/result.h"
#include "common/vfs.h"
struct CF_PLACEHOLDER_BASIC_INFO; struct CF_PLACEHOLDER_BASIC_INFO;
@ -89,10 +90,10 @@ enum SetPinRecurseMode {
ChildrenOnly ChildrenOnly
}; };
OWNCLOUDSYNC_EXPORT Result<void, QString> setPinState(const FileHandle &handle, PinState state, SetPinRecurseMode mode); OWNCLOUDSYNC_EXPORT Result<OCC::Vfs::ConvertToPlaceholderResult, QString> setPinState(const FileHandle &handle, PinState state, SetPinRecurseMode mode);
OWNCLOUDSYNC_EXPORT Result<void, QString> createPlaceholderInfo(const QString &path, time_t modtime, qint64 size, const QByteArray &fileId); OWNCLOUDSYNC_EXPORT Result<void, QString> createPlaceholderInfo(const QString &path, time_t modtime, qint64 size, const QByteArray &fileId);
OWNCLOUDSYNC_EXPORT Result<void, QString> updatePlaceholderInfo(const FileHandle &handle, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath = QString()); OWNCLOUDSYNC_EXPORT Result<OCC::Vfs::ConvertToPlaceholderResult, QString> updatePlaceholderInfo(const FileHandle &handle, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath = QString());
OWNCLOUDSYNC_EXPORT Result<void, QString> convertToPlaceholder(const FileHandle &handle, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath); OWNCLOUDSYNC_EXPORT Result<OCC::Vfs::ConvertToPlaceholderResult, QString> convertToPlaceholder(const FileHandle &handle, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath);
} }

View file

@ -111,10 +111,15 @@ Result<void, QString> VfsCfApi::updateMetadata(const QString &filePath, time_t m
const auto localPath = QDir::toNativeSeparators(filePath); const auto localPath = QDir::toNativeSeparators(filePath);
const auto handle = cfapi::handleForPath(localPath); const auto handle = cfapi::handleForPath(localPath);
if (handle) { if (handle) {
return cfapi::updatePlaceholderInfo(handle, modtime, size, fileId); auto result = cfapi::updatePlaceholderInfo(handle, modtime, size, fileId);
if (result) {
return {};
} else {
return result.error();
}
} else { } else {
qCWarning(lcCfApi) << "Couldn't update metadata for non existing file" << localPath; qCWarning(lcCfApi) << "Couldn't update metadata for non existing file" << localPath;
return "Couldn't update metadata"; return QStringLiteral("Couldn't update metadata");
} }
} }
@ -150,7 +155,7 @@ Result<void, QString> VfsCfApi::dehydratePlaceholder(const SyncFileItem &item)
return {}; return {};
} }
Result<void, QString> VfsCfApi::convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &replacesFile) Result<Vfs::ConvertToPlaceholderResult, QString> VfsCfApi::convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &replacesFile)
{ {
const auto localPath = QDir::toNativeSeparators(filename); const auto localPath = QDir::toNativeSeparators(filename);
const auto replacesPath = QDir::toNativeSeparators(replacesFile); const auto replacesPath = QDir::toNativeSeparators(replacesFile);

View file

@ -43,7 +43,7 @@ public:
Result<void, QString> createPlaceholder(const SyncFileItem &item) override; Result<void, QString> createPlaceholder(const SyncFileItem &item) override;
Result<void, QString> dehydratePlaceholder(const SyncFileItem &item) override; Result<void, QString> dehydratePlaceholder(const SyncFileItem &item) override;
Result<void, QString> convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &replacesFile) override; Result<Vfs::ConvertToPlaceholderResult, QString> convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &replacesFile) override;
bool needsMetadataUpdate(const SyncFileItem &) override; bool needsMetadataUpdate(const SyncFileItem &) override;
bool isDehydratedPlaceholder(const QString &filePath) override; bool isDehydratedPlaceholder(const QString &filePath) override;

View file

@ -122,10 +122,10 @@ Result<void, QString> VfsSuffix::dehydratePlaceholder(const SyncFileItem &item)
return {}; return {};
} }
Result<void, QString> VfsSuffix::convertToPlaceholder(const QString &, const SyncFileItem &, const QString &) Result<Vfs::ConvertToPlaceholderResult, QString> VfsSuffix::convertToPlaceholder(const QString &, const SyncFileItem &, const QString &)
{ {
// Nothing necessary // Nothing necessary
return {}; return Vfs::ConvertToPlaceholderResult::Ok;
} }
bool VfsSuffix::isDehydratedPlaceholder(const QString &filePath) bool VfsSuffix::isDehydratedPlaceholder(const QString &filePath)

View file

@ -41,7 +41,7 @@ public:
Result<void, QString> createPlaceholder(const SyncFileItem &item) override; Result<void, QString> createPlaceholder(const SyncFileItem &item) override;
Result<void, QString> dehydratePlaceholder(const SyncFileItem &item) override; Result<void, QString> dehydratePlaceholder(const SyncFileItem &item) override;
Result<void, QString> convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &) override; Result<Vfs::ConvertToPlaceholderResult, QString> convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &) override;
bool needsMetadataUpdate(const SyncFileItem &) override { return false; } bool needsMetadataUpdate(const SyncFileItem &) override { return false; }
bool isDehydratedPlaceholder(const QString &filePath) override; bool isDehydratedPlaceholder(const QString &filePath) override;

View file

@ -112,10 +112,10 @@ Result<void, QString> VfsXAttr::dehydratePlaceholder(const SyncFileItem &item)
return {}; return {};
} }
Result<void, QString> VfsXAttr::convertToPlaceholder(const QString &, const SyncFileItem &, const QString &) Result<Vfs::ConvertToPlaceholderResult, QString> VfsXAttr::convertToPlaceholder(const QString &, const SyncFileItem &, const QString &)
{ {
// Nothing necessary // Nothing necessary
return {}; return {ConvertToPlaceholderResult::Ok};
} }
bool VfsXAttr::needsMetadataUpdate(const SyncFileItem &) bool VfsXAttr::needsMetadataUpdate(const SyncFileItem &)

View file

@ -41,7 +41,7 @@ public:
Result<void, QString> createPlaceholder(const SyncFileItem &item) override; Result<void, QString> createPlaceholder(const SyncFileItem &item) override;
Result<void, QString> dehydratePlaceholder(const SyncFileItem &item) override; Result<void, QString> dehydratePlaceholder(const SyncFileItem &item) override;
Result<void, QString> convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &replacesFile) override; Result<ConvertToPlaceholderResult, QString> convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &replacesFile) override;
bool needsMetadataUpdate(const SyncFileItem &item) override; bool needsMetadataUpdate(const SyncFileItem &item) override;
bool isDehydratedPlaceholder(const QString &filePath) override; bool isDehydratedPlaceholder(const QString &filePath) override;