mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-22 13:05:51 +03:00
Create placeholder while dehydrating if needed
When replacing an OnlineOnly file by another one, the file maintains it OnlineOnly pin state, but it is converted to a regular file. So, the dehydration should convert the regular file to a (dehydrated) placeholder instead of trying to update the (non-existing) placeholder. Closes #4274 Signed-off-by: Dries Mys <dries.mys@my-dreams.be>
This commit is contained in:
parent
759c2a246c
commit
9256417612
2 changed files with 62 additions and 18 deletions
|
@ -796,29 +796,41 @@ OCC::Result<OCC::Vfs::ConvertToPlaceholderResult, QString> OCC::CfApiWrapper::de
|
|||
return {QString{"Could not update metadata due to invalid modification time for %1: %2"}.arg(path).arg(modtime)};
|
||||
}
|
||||
|
||||
const auto info = findPlaceholderInfo(path);
|
||||
if (!info) {
|
||||
return { "Can't update non existing placeholder info" };
|
||||
}
|
||||
|
||||
const auto fileIdentity = QString::fromUtf8(fileId).toStdWString();
|
||||
const auto fileIdentitySize = (fileIdentity.length() + 1) * sizeof(wchar_t);
|
||||
|
||||
CF_FILE_RANGE dehydrationRange;
|
||||
dehydrationRange.StartingOffset.QuadPart = 0;
|
||||
dehydrationRange.Length.QuadPart = size;
|
||||
const auto info = findPlaceholderInfo(path);
|
||||
if (info) {
|
||||
CF_FILE_RANGE dehydrationRange;
|
||||
dehydrationRange.StartingOffset.QuadPart = 0;
|
||||
dehydrationRange.Length.QuadPart = size;
|
||||
|
||||
const qint64 result = CfUpdatePlaceholder(handleForPath(path).get(), nullptr,
|
||||
fileIdentity.data(), sizeToDWORD(fileIdentitySize),
|
||||
&dehydrationRange,
|
||||
1,
|
||||
CF_UPDATE_FLAG_MARK_IN_SYNC | CF_UPDATE_FLAG_DEHYDRATE,
|
||||
nullptr,
|
||||
nullptr);
|
||||
const qint64 result = CfUpdatePlaceholder(handleForPath(path).get(),
|
||||
nullptr,
|
||||
fileIdentity.data(),
|
||||
sizeToDWORD(fileIdentitySize),
|
||||
&dehydrationRange,
|
||||
1,
|
||||
CF_UPDATE_FLAG_MARK_IN_SYNC | CF_UPDATE_FLAG_DEHYDRATE,
|
||||
nullptr,
|
||||
nullptr);
|
||||
|
||||
if (result != S_OK) {
|
||||
qCWarning(lcCfApiWrapper) << "Couldn't update placeholder info for" << path << ":" << QString::fromWCharArray(_com_error(result).ErrorMessage());
|
||||
return { "Couldn't update placeholder info" };
|
||||
if (result != S_OK) {
|
||||
qCWarning(lcCfApiWrapper) << "Couldn't update placeholder info for" << path << ":" << QString::fromWCharArray(_com_error(result).ErrorMessage());
|
||||
return {"Couldn't update placeholder info"};
|
||||
}
|
||||
} else {
|
||||
const qint64 result = CfConvertToPlaceholder(handleForPath(path).get(),
|
||||
fileIdentity.data(),
|
||||
sizeToDWORD(fileIdentitySize),
|
||||
CF_CONVERT_FLAG_MARK_IN_SYNC | CF_CONVERT_FLAG_DEHYDRATE,
|
||||
nullptr,
|
||||
nullptr);
|
||||
|
||||
if (result != S_OK) {
|
||||
qCWarning(lcCfApiWrapper) << "Couldn't convert to placeholder" << path << ":" << QString::fromWCharArray(_com_error(result).ErrorMessage());
|
||||
return {"Couldn't convert to placeholder"};
|
||||
}
|
||||
}
|
||||
|
||||
return OCC::Vfs::ConvertToPlaceholderResult::Ok;
|
||||
|
|
|
@ -120,6 +120,38 @@ private slots:
|
|||
QTest::newRow("skip local discovery") << false;
|
||||
}
|
||||
|
||||
void testReplaceOnlineOnlyFile()
|
||||
{
|
||||
FakeFolder fakeFolder{FileInfo{}};
|
||||
auto vfs = setupVfs(fakeFolder);
|
||||
|
||||
// Create a new local (non-placeholder) file
|
||||
fakeFolder.localModifier().insert("file");
|
||||
QVERIFY(!vfs->pinState("file").isValid());
|
||||
|
||||
CopyFile(QString(fakeFolder.localPath() + "file").toStdWString().data(), QString(fakeFolder.localPath() + "file1").toStdWString().data(), false);
|
||||
|
||||
// Sync the files: files should be converted to placeholder files
|
||||
QVERIFY(fakeFolder.syncOnce());
|
||||
QVERIFY(vfs->pinState("file").isValid());
|
||||
|
||||
// Convert to Online Only
|
||||
::setPinState(fakeFolder.localPath() + "file", PinState::OnlineOnly, cfapi::Recurse);
|
||||
|
||||
QVERIFY(fakeFolder.syncOnce());
|
||||
QCOMPARE(*vfs->pinState("file"), PinState::OnlineOnly);
|
||||
CFVERIFY_VIRTUAL(fakeFolder, "file");
|
||||
|
||||
// Replace the file
|
||||
CopyFile(QString(fakeFolder.localPath() + "file1").toStdWString().data(), QString(fakeFolder.localPath() + "file").toStdWString().data(), false);
|
||||
|
||||
// Sync again: file should be correctly dehydrated again without error.
|
||||
QVERIFY(fakeFolder.syncOnce());
|
||||
QVERIFY(vfs->pinState("file").isValid());
|
||||
QCOMPARE(*vfs->pinState("file"), PinState::OnlineOnly);
|
||||
CFVERIFY_VIRTUAL(fakeFolder, "file");
|
||||
}
|
||||
|
||||
void testVirtualFileLifecycle()
|
||||
{
|
||||
QFETCH(bool, doLocalDiscovery);
|
||||
|
|
Loading…
Reference in a new issue