mirror of
https://github.com/chylex/Nextcloud-Desktop.git
synced 2025-05-29 01: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:
parent
d8873c18a1
commit
6c5fa1dadd
src
@ -143,7 +143,14 @@ public:
|
|||||||
virtual bool updateMetadata(const QString &filePath, time_t modtime, quint64 size, const QByteArray &fileId, QString *error) = 0;
|
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.
|
/// 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.
|
/** Convert a new file to a hydrated placeholder.
|
||||||
*
|
*
|
||||||
@ -247,7 +254,8 @@ public:
|
|||||||
bool isHydrating() const override { return false; }
|
bool isHydrating() const override { return false; }
|
||||||
|
|
||||||
bool updateMetadata(const QString &, time_t, quint64, const QByteArray &, QString *) override { return true; }
|
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 {}
|
void convertToPlaceholder(const QString &, const SyncFileItem &, const QString &) override {}
|
||||||
|
|
||||||
bool isDehydratedPlaceholder(const QString &) override { return false; }
|
bool isDehydratedPlaceholder(const QString &) override { return false; }
|
||||||
|
@ -417,31 +417,29 @@ void PropagateDownloadFile::startAfterIsEncryptedIsChecked()
|
|||||||
auto &syncOptions = propagator()->syncOptions();
|
auto &syncOptions = propagator()->syncOptions();
|
||||||
auto &vfs = syncOptions._vfs;
|
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) {
|
if (_item->_type == ItemTypeVirtualFileDehydration) {
|
||||||
_item->_type = ItemTypeVirtualFile;
|
QString fsPath = propagator()->getFilePath(_item->_file);
|
||||||
// TODO: Could dehydrate without wiping the file entirely
|
if (!FileSystem::verifyFileUnchanged(fsPath, _item->_previousSize, _item->_previousModtime)) {
|
||||||
// TODO: That would be useful as it could preserve file attributes (pins)
|
propagator()->_anotherSyncNeeded = true;
|
||||||
auto fn = propagator()->getFilePath(_item->_file);
|
done(SyncFileItem::SoftError, tr("File has changed since discovery"));
|
||||||
qCDebug(lcPropagateDownload) << "dehydration: wiping base file" << fn;
|
return;
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
if (vfs->mode() == Vfs::Off && _item->_type == ItemTypeVirtualFile) {
|
||||||
qCWarning(lcPropagateDownload) << "ignored virtual file type of" << _item->_file;
|
qCWarning(lcPropagateDownload) << "ignored virtual file type of" << _item->_file;
|
||||||
_item->_type = ItemTypeFile;
|
_item->_type = ItemTypeFile;
|
||||||
}
|
}
|
||||||
if (_item->_type == ItemTypeVirtualFile) {
|
if (_item->_type == ItemTypeVirtualFile) {
|
||||||
auto fn = propagator()->getFilePath(_item->_file);
|
qCDebug(lcPropagateDownload) << "creating virtual file" << _item->_file;
|
||||||
qCDebug(lcPropagateDownload) << "creating virtual file" << fn;
|
vfs->createPlaceholder(*_item);
|
||||||
|
|
||||||
vfs->createPlaceholder(propagator()->_localDir, *_item);
|
|
||||||
updateMetadata(false);
|
updateMetadata(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -59,10 +59,10 @@ bool VfsSuffix::updateMetadata(const QString &filePath, time_t modtime, quint64,
|
|||||||
return true;
|
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
|
// 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);
|
QFile file(fn);
|
||||||
file.open(QFile::ReadWrite | QFile::Truncate);
|
file.open(QFile::ReadWrite | QFile::Truncate);
|
||||||
file.write(" ");
|
file.write(" ");
|
||||||
@ -70,6 +70,14 @@ void VfsSuffix::createPlaceholder(const QString &syncFolder, const SyncFileItem
|
|||||||
FileSystem::setModTime(fn, item._modtime);
|
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 &)
|
void VfsSuffix::convertToPlaceholder(const QString &, const SyncFileItem &, const QString &)
|
||||||
{
|
{
|
||||||
// Nothing necessary
|
// Nothing necessary
|
||||||
|
@ -39,7 +39,8 @@ public:
|
|||||||
|
|
||||||
bool updateMetadata(const QString &filePath, time_t modtime, quint64 size, const QByteArray &fileId, QString *error) override;
|
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;
|
void convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &) override;
|
||||||
|
|
||||||
bool isDehydratedPlaceholder(const QString &filePath) override;
|
bool isDehydratedPlaceholder(const QString &filePath) override;
|
||||||
|
Loading…
Reference in New Issue
Block a user