Vfs: Switch on/off only when sync isn't running #6936

Avoids some situations that might cause data loss.
This commit is contained in:
Christian Kamm 2019-01-14 15:48:08 +01:00 committed by Kevin Ottens
parent 5728256763
commit b7079289c2
No known key found for this signature in database
GPG key ID: 074BBBCB8DECC9E2
2 changed files with 70 additions and 31 deletions

View file

@ -457,7 +457,8 @@ void AccountSettings::slotCustomContextMenuRequested(const QPoint &pos)
if (Theme::instance()->showVirtualFilesOption() if (Theme::instance()->showVirtualFilesOption()
&& !folder->supportsVirtualFiles() && !folder->supportsVirtualFiles()
&& bestAvailableVfsMode() != Vfs::Off) { && bestAvailableVfsMode() != Vfs::Off
&& !folder->isVfsOnOffSwitchPending()) {
ac = menu->addAction(tr("Enable virtual file support (experimental)...")); ac = menu->addAction(tr("Enable virtual file support (experimental)..."));
connect(ac, &QAction::triggered, this, &AccountSettings::slotEnableVfsCurrentFolder); connect(ac, &QAction::triggered, this, &AccountSettings::slotEnableVfsCurrentFolder);
} }
@ -648,27 +649,43 @@ void AccountSettings::slotEnableVfsCurrentFolder()
if (!enable || !folder) if (!enable || !folder)
return; return;
qCInfo(lcAccountSettings) << "Enabling vfs support for folder" << folder->path(); // It is unsafe to switch on vfs while a sync is running - wait if necessary.
auto connection = std::make_shared<QMetaObject::Connection>();
auto switchVfsOn = [folder, connection, this]() {
if (*connection)
QObject::disconnect(*connection);
// Wipe selective sync blacklist qCInfo(lcAccountSettings) << "Enabling vfs support for folder" << folder->path();
bool ok = false;
auto oldBlacklist = folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, &ok); // Wipe selective sync blacklist
folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, {}); bool ok = false;
for (const auto &entry : oldBlacklist) { auto oldBlacklist = folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, &ok);
folder->journalDb()->avoidReadFromDbOnNextSync(entry); folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, {});
for (const auto &entry : oldBlacklist) {
folder->journalDb()->avoidReadFromDbOnNextSync(entry);
}
// Change the folder vfs mode and load the plugin
folder->setSupportsVirtualFiles(true);
folder->setVfsOnOffSwitchPending(false);
// Wipe pin states to be sure
folder->journalDb()->wipePinStateForPathAndBelow("");
folder->journalDb()->setPinStateForPath("", PinState::OnlineOnly);
FolderMan::instance()->scheduleFolder(folder);
_ui->_folderList->doItemsLayout();
};
if (folder->isSyncRunning()) {
*connection = connect(folder, &Folder::syncFinished, this, switchVfsOn);
folder->setVfsOnOffSwitchPending(true);
folder->slotTerminateSync();
_ui->_folderList->doItemsLayout();
} else {
switchVfsOn();
} }
// Change the folder vfs mode and load the plugin
folder->setSupportsVirtualFiles(true);
// Wipe pin states to be sure
folder->journalDb()->wipePinStateForPathAndBelow("");
folder->journalDb()->setPinStateForPath("", PinState::OnlineOnly);
FolderMan::instance()->scheduleFolder(folder);
// Update the ui: no selective sync, vfs indicator; size changed
_ui->_folderList->doItemsLayout();
}); });
} }
@ -687,7 +704,9 @@ void AccountSettings::slotDisableVfsCurrentFolder()
"are currently marked as 'available online only' will be downloaded." "are currently marked as 'available online only' will be downloaded."
"\n\n" "\n\n"
"The only advantage of disabling virtual file support is that the selective sync feature " "The only advantage of disabling virtual file support is that the selective sync feature "
"will become available again.")); "will become available again."
"\n\n"
"This action will abort any currently running synchronization."));
msgBox->addButton(tr("Disable support"), QMessageBox::AcceptRole); msgBox->addButton(tr("Disable support"), QMessageBox::AcceptRole);
msgBox->addButton(tr("Cancel"), QMessageBox::RejectRole); msgBox->addButton(tr("Cancel"), QMessageBox::RejectRole);
connect(msgBox, &QMessageBox::finished, msgBox, [this, msgBox, folder](int result) { connect(msgBox, &QMessageBox::finished, msgBox, [this, msgBox, folder](int result) {
@ -695,20 +714,36 @@ void AccountSettings::slotDisableVfsCurrentFolder()
if (result != QMessageBox::AcceptRole || !folder) if (result != QMessageBox::AcceptRole || !folder)
return; return;
qCInfo(lcAccountSettings) << "Disabling vfs support for folder" << folder->path(); // It is unsafe to switch off vfs while a sync is running - wait if necessary.
auto connection = std::make_shared<QMetaObject::Connection>();
auto switchVfsOff = [folder, connection, this]() {
if (*connection)
QObject::disconnect(*connection);
// Also wipes virtual files, schedules remote discovery qCInfo(lcAccountSettings) << "Disabling vfs support for folder" << folder->path();
folder->setSupportsVirtualFiles(false);
// Wipe pin states and selective sync db // Also wipes virtual files, schedules remote discovery
folder->journalDb()->wipePinStateForPathAndBelow(""); folder->setSupportsVirtualFiles(false);
folder->journalDb()->setPinStateForPath("", PinState::AlwaysLocal); folder->setVfsOnOffSwitchPending(false);
folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, {});
FolderMan::instance()->scheduleFolder(folder); // Wipe pin states and selective sync db
folder->journalDb()->wipePinStateForPathAndBelow("");
folder->journalDb()->setPinStateForPath("", PinState::AlwaysLocal);
folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, {});
// Update the ui: no selective sync, vfs indicator; size changed FolderMan::instance()->scheduleFolder(folder);
_ui->_folderList->doItemsLayout();
_ui->_folderList->doItemsLayout();
};
if (folder->isSyncRunning()) {
*connection = connect(folder, &Folder::syncFinished, this, switchVfsOff);
folder->setVfsOnOffSwitchPending(true);
folder->slotTerminateSync();
_ui->_folderList->doItemsLayout();
} else {
switchVfsOff();
}
}); });
msgBox->open(); msgBox->open();
} }

View file

@ -341,6 +341,8 @@ void OwncloudWizard::askExperimentalVirtualFilesFeature(const std::function<void
"When a file is opened its contents will be downloaded automatically. " "When a file is opened its contents will be downloaded automatically. "
"Alternatively files can be downloaded manually by using their context menu." "Alternatively files can be downloaded manually by using their context menu."
"\n\n" "\n\n"
"Switching to this mode will abort any currently running synchronization."
"\n\n"
"This is a new, experimental mode. If you decide to use it, please report any " "This is a new, experimental mode. If you decide to use it, please report any "
"issues that come up.")); "issues that come up."));
} else { } else {
@ -352,6 +354,8 @@ void OwncloudWizard::askExperimentalVirtualFilesFeature(const std::function<void
"Instead, a tiny \"%1\" file will be created for each file that exists on the server. " "Instead, a tiny \"%1\" file will be created for each file that exists on the server. "
"The contents can be downloaded by running these files or by using their context menu." "The contents can be downloaded by running these files or by using their context menu."
"\n\n" "\n\n"
"Switching to this mode will abort any currently running synchronization."
"\n\n"
"This is a new, experimental mode. If you decide to use it, please report any " "This is a new, experimental mode. If you decide to use it, please report any "
"issues that come up.") "issues that come up.")
.arg(APPLICATION_DOTVIRTUALFILE_SUFFIX)); .arg(APPLICATION_DOTVIRTUALFILE_SUFFIX));