From: Christian Kamm Date: Wed, 24 Jul 2019 13:25:02 +0000 (+0200) Subject: Vfs: Ensure pins change with (de-)hydration X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~12^2~21^2~468^2~217 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=00dcf3ef598998594694248024ee1eb5097fcf89;p=nextcloud-desktop.git Vfs: Ensure pins change with (de-)hydration Previously an implicit hydration of a file in an online-only folder would not change the pin state and cause a dehydration on the next sync. --- diff --git a/src/libsync/propagatedownload.cpp b/src/libsync/propagatedownload.cpp index d4a68aa04..3cd647d54 100644 --- a/src/libsync/propagatedownload.cpp +++ b/src/libsync/propagatedownload.cpp @@ -1017,11 +1017,11 @@ void PropagateDownloadFile::downloadFinished() if (_conflictRecord.isValid()) propagator()->_journal->setConflictRecord(_conflictRecord); - if (_item->_type == ItemTypeVirtualFileDownload) { + auto vfs = propagator()->syncOptions()._vfs; + if (vfs && vfs->mode() == Vfs::WithSuffix) { // If the virtual file used to have a different name and db - // entry, wipe both now. - auto vfs = propagator()->syncOptions()._vfs; - if (vfs && vfs->mode() == Vfs::WithSuffix) { + // entry, remove it transfer its old pin state. + if (_item->_type == ItemTypeVirtualFileDownload) { QString virtualFile = _item->_file + vfs->fileSuffix(); auto fn = propagator()->getFilePath(virtualFile); qCDebug(lcPropagateDownload) << "Download of previous virtual file finished" << fn; @@ -1035,6 +1035,11 @@ void PropagateDownloadFile::downloadFinished() vfs->setPinState(virtualFile, PinState::Inherited); } } + + // Ensure the pin state isn't contradictory + auto pin = vfs->pinState(_item->_file); + if (pin && *pin == PinState::OnlineOnly) + vfs->setPinState(_item->_file, PinState::Unspecified); } updateMetadata(isConflict); diff --git a/src/libsync/vfs/suffix/vfs_suffix.cpp b/src/libsync/vfs/suffix/vfs_suffix.cpp index 474e7b77e..e9d3ee9a1 100644 --- a/src/libsync/vfs/suffix/vfs_suffix.cpp +++ b/src/libsync/vfs/suffix/vfs_suffix.cpp @@ -89,6 +89,11 @@ void VfsSuffix::dehydratePlaceholder(const SyncFileItem &item) setPinState(item._renameTarget, *pin); setPinState(item._file, PinState::Inherited); } + + // Ensure the pin state isn't contradictory + pin = pinState(item._renameTarget); + if (pin && *pin == PinState::AlwaysLocal) + setPinState(item._renameTarget, PinState::Unspecified); } void VfsSuffix::convertToPlaceholder(const QString &, const SyncFileItem &, const QString &) diff --git a/test/testsyncvirtualfiles.cpp b/test/testsyncvirtualfiles.cpp index 5bf886f49..323c52b36 100644 --- a/test/testsyncvirtualfiles.cpp +++ b/test/testsyncvirtualfiles.cpp @@ -718,11 +718,11 @@ private slots: // Case 4: foo -> bar.oc (db unchanged) fakeFolder.localModifier().rename("case4", "case4-rename" DVSUFFIX); - // Case 5: foo -> bar (db dehydrate) + // Case 5: foo.oc -> bar.oc (db hydrate) fakeFolder.localModifier().rename("case5" DVSUFFIX, "case5-rename" DVSUFFIX); triggerDownload(fakeFolder, "case5"); - // Case 6: foo.oc -> bar.oc (db hydrate) + // Case 6: foo -> bar (db dehydrate) fakeFolder.localModifier().rename("case6", "case6-rename"); markForDehydration(fakeFolder, "case6"); @@ -1175,6 +1175,45 @@ private slots: QVERIFY(fakeFolder.currentLocalState().find("onlinerenamed2/file1rename" DVSUFFIX)); QCOMPARE(*vfs->pinState("onlinerenamed2/file1rename" DVSUFFIX), PinState::OnlineOnly); } + + void testIncompatiblePins() + { + FakeFolder fakeFolder{ FileInfo() }; + auto vfs = setupVfs(fakeFolder); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + auto setPin = [&] (const QByteArray &path, PinState state) { + fakeFolder.syncJournal().internalPinStates().setForPath(path, state); + }; + + fakeFolder.remoteModifier().mkdir("local"); + fakeFolder.remoteModifier().mkdir("online"); + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + setPin("local", PinState::AlwaysLocal); + setPin("online", PinState::OnlineOnly); + + fakeFolder.localModifier().insert("local/file1"); + fakeFolder.localModifier().insert("online/file1"); + QVERIFY(fakeFolder.syncOnce()); + + markForDehydration(fakeFolder, "local/file1"); + triggerDownload(fakeFolder, "online/file1"); + + // the sync sets the changed files pin states to unspecified + QVERIFY(fakeFolder.syncOnce()); + + QVERIFY(fakeFolder.currentLocalState().find("online/file1")); + QVERIFY(fakeFolder.currentLocalState().find("local/file1" DVSUFFIX)); + QCOMPARE(*vfs->pinState("online/file1"), PinState::Unspecified); + QCOMPARE(*vfs->pinState("local/file1" DVSUFFIX), PinState::Unspecified); + + // no change on another sync + QVERIFY(fakeFolder.syncOnce()); + QVERIFY(fakeFolder.currentLocalState().find("online/file1")); + QVERIFY(fakeFolder.currentLocalState().find("local/file1" DVSUFFIX)); + } }; QTEST_GUILESS_MAIN(TestSyncVirtualFiles)