1
0
mirror of https://github.com/chylex/Nextcloud-Desktop.git synced 2025-05-06 23:34:09 +02:00

Vfs: dehydration is separate action

Allows for better attribute preservation.

Also add verifyFileUnchanged() call before dehydration to avoid data
loss when discovery takes a while.
This commit is contained in:
Christian Kamm 2019-02-01 11:23:00 +01:00 committed by Kevin Ottens
parent d8873c18a1
commit 6c5fa1dadd
No known key found for this signature in database
GPG Key ID: 074BBBCB8DECC9E2
4 changed files with 37 additions and 22 deletions

View File

@ -143,7 +143,14 @@ 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 SyncFileItem &item) = 0;
virtual void createPlaceholder(const SyncFileItem &item) = 0;
/** Convert a hydrated placeholder to a dehydrated one. Called from PropagateDownlaod.
*
* This is different from delete+create because preserving some file metadata
* (like pin states) may be essential for some vfs plugins.
*/
virtual void dehydratePlaceholder(const SyncFileItem &item) = 0;
/** Convert a new file to a hydrated placeholder.
*
@ -247,7 +254,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 SyncFileItem &) override {}
void createPlaceholder(const SyncFileItem &) override {}
void dehydratePlaceholder(const SyncFileItem &) override {}
void convertToPlaceholder(const QString &, const SyncFileItem &, const QString &) override {}
bool isDehydratedPlaceholder(const QString &) override { return false; }

View File

@ -417,31 +417,29 @@ void PropagateDownloadFile::startAfterIsEncryptedIsChecked()
auto &syncOptions = propagator()->syncOptions();
auto &vfs = syncOptions._vfs;
// For virtual files just create the file and be done
// For virtual files just dehydrate or create the file and be done
if (_item->_type == ItemTypeVirtualFileDehydration) {
_item->_type = ItemTypeVirtualFile;
// TODO: Could dehydrate without wiping the file entirely
// TODO: That would be useful as it could preserve file attributes (pins)
auto fn = propagator()->getFilePath(_item->_file);
qCDebug(lcPropagateDownload) << "dehydration: wiping base file" << fn;
propagator()->_journal->deleteFileRecord(_item->_file);
QFile::remove(fn);
if (vfs->mode() == Vfs::WithSuffix) {
// Normally new suffix-virtual files already have the suffix included in the path
// but for dehydrations that isn't the case. Adjust it here.
_item->_file.append(vfs->fileSuffix());
QString fsPath = propagator()->getFilePath(_item->_file);
if (!FileSystem::verifyFileUnchanged(fsPath, _item->_previousSize, _item->_previousModtime)) {
propagator()->_anotherSyncNeeded = true;
done(SyncFileItem::SoftError, tr("File has changed since discovery"));
return;
}
qCDebug(lcPropagateDownload) << "dehydrating file" << _item->_file;
_item->_type = ItemTypeVirtualFile; // Needed?
vfs->dehydratePlaceholder(*_item);
propagator()->_journal->deleteFileRecord(_item->_file);
updateMetadata(false);
return;
}
if (vfs->mode() == Vfs::Off && _item->_type == ItemTypeVirtualFile) {
qCWarning(lcPropagateDownload) << "ignored virtual file type of" << _item->_file;
_item->_type = ItemTypeFile;
}
if (_item->_type == ItemTypeVirtualFile) {
auto fn = propagator()->getFilePath(_item->_file);
qCDebug(lcPropagateDownload) << "creating virtual file" << fn;
vfs->createPlaceholder(propagator()->_localDir, *_item);
qCDebug(lcPropagateDownload) << "creating virtual file" << _item->_file;
vfs->createPlaceholder(*_item);
updateMetadata(false);
return;
}

View File

@ -59,10 +59,10 @@ bool VfsSuffix::updateMetadata(const QString &filePath, time_t modtime, quint64,
return true;
}
void VfsSuffix::createPlaceholder(const QString &syncFolder, const SyncFileItem &item)
void VfsSuffix::createPlaceholder(const SyncFileItem &item)
{
// The concrete shape of the placeholder is also used in isDehydratedPlaceholder() below
QString fn = syncFolder + item._file;
QString fn = _setupParams.filesystemPath + item._file;
QFile file(fn);
file.open(QFile::ReadWrite | QFile::Truncate);
file.write(" ");
@ -70,6 +70,14 @@ void VfsSuffix::createPlaceholder(const QString &syncFolder, const SyncFileItem
FileSystem::setModTime(fn, item._modtime);
}
void VfsSuffix::dehydratePlaceholder(const SyncFileItem &item)
{
QFile::remove(_setupParams.filesystemPath + item._file);
SyncFileItem virtualItem(item);
virtualItem._file.append(fileSuffix());
createPlaceholder(virtualItem);
}
void VfsSuffix::convertToPlaceholder(const QString &, const SyncFileItem &, const QString &)
{
// Nothing necessary

View File

@ -39,7 +39,8 @@ public:
bool updateMetadata(const QString &filePath, time_t modtime, quint64 size, const QByteArray &fileId, QString *error) override;
void createPlaceholder(const QString &syncFolder, const SyncFileItem &item) override;
void createPlaceholder(const SyncFileItem &item) override;
void dehydratePlaceholder(const SyncFileItem &item) override;
void convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &) override;
bool isDehydratedPlaceholder(const QString &filePath) override;