Skip to content

Commit

Permalink
Merge pull request #5906 from nextcloud/backport/5890/stable-3.9
Browse files Browse the repository at this point in the history
[stable-3.9] Create placeholder while dehydrating if needed
  • Loading branch information
mgallien committed Jul 20, 2023
2 parents f8dae64 + 241101b commit ecb5b5c
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 20 deletions.
52 changes: 32 additions & 20 deletions src/libsync/vfs/cfapi/cfapiwrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 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" };
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);

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;
Expand Down
32 changes: 32 additions & 0 deletions test/testsynccfapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit ecb5b5c

Please sign in to comment.