diff --git a/CMakeLists.txt b/CMakeLists.txt index 9fd4b1220..7d8bcfe12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,7 +102,7 @@ add_feature_info(AppImageUpdate WITH_APPIMAGEUPDATER "Built-in libappimageupdate option(WITH_EXTERNAL_BRANDING "A URL to an external branding repo" "") # specify additional vfs plugins -set(VIRTUAL_FILE_SYSTEM_PLUGINS off cfapi xattr CACHE STRING "Name of internal plugin in src/libsync/vfs or the locations of virtual file plugins") +set(VIRTUAL_FILE_SYSTEM_PLUGINS off cfapi openvfs CACHE STRING "Name of internal plugin in src/libsync/vfs or the locations of virtual file plugins") if(APPLE) set( SOCKETAPI_TEAM_IDENTIFIER_PREFIX "" CACHE STRING "SocketApi prefix (including a following dot) that must match the codesign key's TeamIdentifier/Organizational Unit" ) diff --git a/src/gui/folderdefinition.cpp b/src/gui/folderdefinition.cpp index f995ece18..a6e40b0a6 100644 --- a/src/gui/folderdefinition.cpp +++ b/src/gui/folderdefinition.cpp @@ -105,7 +105,7 @@ FolderDefinition FolderDefinition::load(QSettings &settings) QString vfsModeString = settings.value("virtualFilesMode").toString(); - const auto vfs = Utility::isWindows() ? Vfs::Mode::WindowsCfApi : Vfs::Mode::XAttr; + const auto vfs = Utility::isWindows() ? Vfs::Mode::WindowsCfApi : Vfs::Mode::OpenVFS; if (auto result = VfsPluginManager::instance().prepare(folder.localPath(), folder.accountUUID(), vfs); result) { vfsModeString = Utility::enumToString(vfs); } else { diff --git a/src/libsync/vfs/vfs.cpp b/src/libsync/vfs/vfs.cpp index ab5fcdafb..7261b2de0 100644 --- a/src/libsync/vfs/vfs.cpp +++ b/src/libsync/vfs/vfs.cpp @@ -55,8 +55,8 @@ Optional Vfs::modeFromString(const QString &str) return Mode::Off; } else if (str == QLatin1String("cfapi")) { return Mode::WindowsCfApi; - } else if (str == QLatin1String("xattr")) { - return Mode::XAttr; + } else if (str == QLatin1String("openvfs")) { + return Mode::OpenVFS; } return {}; } @@ -71,8 +71,8 @@ QString Utility::enumToString(Vfs::Mode mode) return QStringLiteral("cfapi"); case Vfs::Mode::Off: return QStringLiteral("off"); - case Vfs::Mode::XAttr: - return QStringLiteral("xattr"); + case Vfs::Mode::OpenVFS: + return QStringLiteral("openvfs"); } Q_UNREACHABLE(); } @@ -136,8 +136,8 @@ Vfs::Mode OCC::VfsPluginManager::bestAvailableVfsMode() const { if (isVfsPluginAvailable(Vfs::Mode::WindowsCfApi)) { return Vfs::Mode::WindowsCfApi; - } else if (isVfsPluginAvailable(Vfs::Mode::XAttr)) { - return Vfs::Mode::XAttr; + } else if (isVfsPluginAvailable(Vfs::Mode::OpenVFS)) { + return Vfs::Mode::OpenVFS; } else if (isVfsPluginAvailable(Vfs::Mode::Off)) { return Vfs::Mode::Off; } diff --git a/src/libsync/vfs/vfs.h b/src/libsync/vfs/vfs.h index 7429b7ca4..3e8208f13 100644 --- a/src/libsync/vfs/vfs.h +++ b/src/libsync/vfs/vfs.h @@ -99,7 +99,7 @@ class OPENCLOUD_SYNC_EXPORT Vfs : public QObject * Currently plugins and modes are one-to-one but that's not required. * The raw integer values are used in Qml */ - enum class Mode : uint8_t { Off = 0, WindowsCfApi = 1, XAttr = 2 }; + enum class Mode : uint8_t { Off = 0, WindowsCfApi = 1, OpenVFS = 2 }; Q_ENUM(Mode) enum class ConvertToPlaceholderResult : uint8_t { Ok, Locked }; Q_ENUM(ConvertToPlaceholderResult) diff --git a/src/plugins/vfs/xattr/CMakeLists.txt b/src/plugins/vfs/openvfs/CMakeLists.txt similarity index 69% rename from src/plugins/vfs/xattr/CMakeLists.txt rename to src/plugins/vfs/openvfs/CMakeLists.txt index 003156fb0..ac402e1e2 100644 --- a/src/plugins/vfs/xattr/CMakeLists.txt +++ b/src/plugins/vfs/openvfs/CMakeLists.txt @@ -1,19 +1,19 @@ if (NOT WIN32) - find_package(OpenVFS QUIET ) + find_package(OpenVFS 0.1.0 QUIET) set_package_properties(OpenVFS PROPERTIES TYPE OPTIONAL DESCRIPTION "A Virtual Filesystem Layer for cloud storages for the free desktop" - URL "https://github.com/dragotin/openvfs") + URL "https://github.com/opencloud-eu/openvfs/") if(TARGET OpenVFS::OpenVFS) get_target_property (OPEN_VFS_CONFIG OpenVFS::OpenVFS IMPORTED_CONFIGURATIONS) get_target_property (OPEN_VFS_PATH OpenVFS::OpenVFS IMPORTED_LOCATION_${OPEN_VFS_CONFIG}) message(STATUS "Using OpenVFS ${OPEN_VFS_CONFIG} (${OPEN_VFS_PATH})") - add_vfs_plugin(NAME xattr + add_vfs_plugin(NAME openvfs SRC - vfs_xattr.cpp + vfs_openvfs.cpp LIBS OpenVFS::LibOpenVFS ) - target_compile_definitions(vfs_xattr PRIVATE OPENVFS_EXE=\"${OPEN_VFS_PATH}\") + target_compile_definitions(vfs_openvfs PRIVATE OPENVFS_EXE=\"${OPEN_VFS_PATH}\") endif() endif() diff --git a/src/plugins/vfs/xattr/vfs_xattr.cpp b/src/plugins/vfs/openvfs/vfs_openvfs.cpp similarity index 63% rename from src/plugins/vfs/xattr/vfs_xattr.cpp rename to src/plugins/vfs/openvfs/vfs_openvfs.cpp index f6496419d..7a569c952 100644 --- a/src/plugins/vfs/xattr/vfs_xattr.cpp +++ b/src/plugins/vfs/openvfs/vfs_openvfs.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ -#include "vfs_xattr.h" +#include "vfs_openvfs.h" #include "account.h" #include "common/chronoelapsedtimer.h" @@ -15,7 +15,7 @@ #include "syncfileitem.h" #include "vfs/hydrationjob.h" -#include +#include #include #include @@ -27,7 +27,7 @@ using namespace std::chrono_literals; using namespace Qt::StringLiterals; -Q_LOGGING_CATEGORY(lcVfsXAttr, "sync.vfs.xattr", QtInfoMsg) +Q_LOGGING_CATEGORY(lcOpenVFS, "sync.vfs.xattr", QtInfoMsg) namespace { @@ -42,9 +42,9 @@ OCC::FileSystem::Path openVFSExePath() } -QByteArray xattrOwnerString(const QUuid &accountUuid) +QString xattrOwnerString(const QUuid &accountUuid) { - return OCC::Theme::instance()->appName().toUtf8() + ":" + accountUuid.toByteArray(QUuid::WithoutBraces); + return u"%1:%2"_s.arg(OCC::Theme::instance()->appName(), accountUuid.toString(QUuid::WithoutBraces)); } OCC::FileSystem::Path openVFSConfigFilePath() @@ -62,29 +62,29 @@ OCC::FileSystem::Path openVFSConfigFilePath() return {}; } -OpenVfsAttributes::PlaceHolderAttributes placeHolderAttributes(const std::filesystem::path &path) +OpenVFS::PlaceHolderAttributes placeHolderAttributes(const std::filesystem::path &path) { - const auto data = OCC::FileSystem::Xattr::getxattr(path, QString::fromUtf8(OpenVfsConstants::XAttributeNames::Data)); + const auto data = OCC::FileSystem::Xattr::getxattr(path, QString::fromUtf8(OpenVFS::Constants::XAttributeNames::Data)); if (!data) { - qCWarning(lcVfsXAttr) << u"No OpenVFS xattr found for" << path.native(); + qCWarning(lcOpenVFS) << u"No OpenVFS xattr found for" << path.native(); } - return OpenVfsAttributes::PlaceHolderAttributes::fromData(path, data ? std::vector{data->cbegin(), data->cend()} : std::vector{}); + return OpenVFS::PlaceHolderAttributes::fromData(path, data ? std::vector{data->cbegin(), data->cend()} : std::vector{}); } -OpenVfsAttributes::PlaceHolderAttributes placeHolderAttributes(const QString &path) +OpenVFS::PlaceHolderAttributes placeHolderAttributes(const QString &path) { return placeHolderAttributes(OCC::FileSystem::toFilesystemPath(path)); } -OCC::Result setPlaceholderAttributes(const OpenVfsAttributes::PlaceHolderAttributes &attributes) +OCC::Result setPlaceholderAttributes(const OpenVFS::PlaceHolderAttributes &attributes) { Q_ASSERT(attributes.validate()); const auto data = attributes.toData(); - return OCC::FileSystem::Xattr::setxattr(attributes.absolutePath, QString::fromUtf8(OpenVfsConstants::XAttributeNames::Data), + return OCC::FileSystem::Xattr::setxattr(attributes.absolutePath, QString::fromUtf8(OpenVFS::Constants::XAttributeNames::Data), {reinterpret_cast(data.data()), static_cast(data.size())}); } -OCC::Result setPlaceholderAttributes(const OpenVfsAttributes::PlaceHolderAttributes &attributes, time_t modtime) +OCC::Result setPlaceholderAttributes(const OpenVFS::PlaceHolderAttributes &attributes, time_t modtime) { if (const auto result = setPlaceholderAttributes(attributes); !result) { return result; @@ -93,35 +93,35 @@ OCC::Result setPlaceholderAttributes(const OpenVfsAttributes::Pla return {}; } -OpenVfsConstants::PinStates convertPinState(OCC::PinState pState) +OpenVFS::Constants::PinStates convertPinState(OCC::PinState pState) { switch (pState) { case OCC::PinState::AlwaysLocal: - return OpenVfsConstants::PinStates::AlwaysLocal; + return OpenVFS::Constants::PinStates::AlwaysLocal; case OCC::PinState::Inherited: - return OpenVfsConstants::PinStates::Inherited; + return OpenVFS::Constants::PinStates::Inherited; case OCC::PinState::OnlineOnly: - return OpenVfsConstants::PinStates::OnlineOnly; + return OpenVFS::Constants::PinStates::OnlineOnly; case OCC::PinState::Excluded: - return OpenVfsConstants::PinStates::OnlineOnly; + return OpenVFS::Constants::PinStates::OnlineOnly; case OCC::PinState::Unspecified: - return OpenVfsConstants::PinStates::Unspecified; + return OpenVFS::Constants::PinStates::Unspecified; }; Q_UNREACHABLE(); } -OCC::PinState convertPinState(OpenVfsConstants::PinStates pState) +OCC::PinState convertPinState(OpenVFS::Constants::PinStates pState) { switch (pState) { - case OpenVfsConstants::PinStates::AlwaysLocal: + case OpenVFS::Constants::PinStates::AlwaysLocal: return OCC::PinState::AlwaysLocal; - case OpenVfsConstants::PinStates::Inherited: + case OpenVFS::Constants::PinStates::Inherited: return OCC::PinState::Inherited; - case OpenVfsConstants::PinStates::OnlineOnly: + case OpenVFS::Constants::PinStates::OnlineOnly: return OCC::PinState::OnlineOnly; - case OpenVfsConstants::PinStates::Unspecified: + case OpenVFS::Constants::PinStates::Unspecified: return OCC::PinState::Unspecified; - case OpenVfsConstants::PinStates::Excluded: + case OpenVFS::Constants::PinStates::Excluded: return OCC::PinState::Excluded; } Q_UNREACHABLE(); @@ -174,46 +174,53 @@ QByteArray parseMangledPath(QByteArrayView path) namespace OCC { -VfsXAttr::VfsXAttr(QObject *parent) +OpenVFS::OpenVFS(QObject *parent) : Vfs(parent) { } -VfsXAttr::~VfsXAttr() = default; +OpenVFS::~OpenVFS() = default; -Vfs::Mode VfsXAttr::mode() const +Vfs::Mode OpenVFS::mode() const { - return Mode::XAttr; + return Mode::OpenVFS; } -void VfsXAttr::startImpl(const VfsSetupParams ¶ms) +void OpenVFS::startImpl(const VfsSetupParams ¶ms) { - qCDebug(lcVfsXAttr, "Start XAttr VFS"); + qCDebug(lcOpenVFS, "Start OpenVFS VFS"); // Lets claim the sync root directory for us // set the owner to opencloud to claim it - if (!FileSystem::Xattr::setxattr(params.root(), QString::fromUtf8(OpenVfsConstants::XAttributeNames::Owner), xattrOwnerString(params.account->uuid()))) { - Q_EMIT error(tr("Unable to claim the sync root for files on demand")); + const auto owner = xattrOwnerString(params.account->uuid()).toStdString(); + if (const auto info = ::OpenVFS::RegistrationInfo::registerFilesystem(params.root(), owner); !info) { + if (info.owner() != owner) { + Q_EMIT error(tr("Unable to claim the sync root for files on demand, the folder is already claimed by %1").arg(info.owner())); + return; + } + Q_EMIT error(tr("Unable to retrieve registration info. Error: %1").arg(info.error())); return; } - qCDebug(lcVfsXAttr) << "Mounting" << openVFSExePath().toString() << params.root().toString(); + qCDebug(lcOpenVFS) << "Mounting" << openVFSExePath().toString() << params.root().toString(); _openVfsProcess = new QProcess(this); // merging the channels and piping the output to our log lead to deadlocks _openVfsProcess->setProcessChannelMode(QProcess::ForwardedChannels); const auto logPrefix = [path = params.root().toString(), this] { return u"[%1 %2] "_s.arg(QString::number(_openVfsProcess->processId()), path); }; - connect(_openVfsProcess, &QProcess::finished, this, [logPrefix, this] { qCFatal(lcVfsXAttr) << logPrefix() << "finished" << _openVfsProcess->exitCode(); }); + connect(_openVfsProcess, &QProcess::finished, this, [logPrefix, this] { qCFatal(lcOpenVFS) << logPrefix() << "finished" << _openVfsProcess->exitCode(); }); connect(_openVfsProcess, &QProcess::started, this, [logPrefix, this] { - qCInfo(lcVfsXAttr) << logPrefix() << u"started"; + qCInfo(lcOpenVFS) << logPrefix() << u"started"; // TODO: // give it time to mount QTimer::singleShot(1s, this, &Vfs::started); }); - connect(_openVfsProcess, &QProcess::errorOccurred, this, [logPrefix, this] { qCWarning(lcVfsXAttr) << logPrefix() << _openVfsProcess->errorString(); }); - _openVfsProcess->start(openVFSExePath().toString(), {u"-d"_s, u"-i"_s, openVFSConfigFilePath().toString(), params.root().toString()}, QIODevice::ReadOnly); + connect(_openVfsProcess, &QProcess::errorOccurred, this, [logPrefix, this] { qCWarning(lcOpenVFS) << logPrefix() << _openVfsProcess->errorString(); }); + _openVfsProcess->start(openVFSExePath().toString(), + {u"-d"_s, u"-i"_s, openVFSConfigFilePath().toString(), u"-o"_s, xattrOwnerString(params.account->uuid()), params.root().toString()}, + QIODevice::ReadOnly); } -void VfsXAttr::stop() +void OpenVFS::stop() { if (_openVfsProcess) { // disconnect qFatal on subprocess exit @@ -224,32 +231,33 @@ void VfsXAttr::stop() } } -void VfsXAttr::unregisterFolder() +void OpenVFS::unregisterFolder() { + ::OpenVFS::RegistrationInfo::unregisterFilesystem({params().root(), xattrOwnerString(params().account->uuid()).toStdString()}); } -bool VfsXAttr::socketApiPinStateActionsShown() const +bool OpenVFS::socketApiPinStateActionsShown() const { return true; } -bool XattrVfsPluginFactory::checkAvailability() const +bool OpenVfsPluginFactory::checkAvailability() const { #ifdef Q_OS_LINUX if (!FileSystem::Path("/dev/fuse").exists()) { - qCWarning(lcVfsXAttr) << u"Fuse is not installed or available on the system"; + qCWarning(lcOpenVFS) << u"Fuse is not installed or available on the system"; return false; } if (QStandardPaths::findExecutable(u"fusermount3"_s).isEmpty()) { - qCWarning(lcVfsXAttr) << u"fusermount3 is not installed on the system"; + qCWarning(lcOpenVFS) << u"fusermount3 is not installed on the system"; return false; } #endif return true; } -Result XattrVfsPluginFactory::prepare(const QString &path, const QUuid &accountUuid) const +Result OpenVfsPluginFactory::prepare(const QString &path, const QUuid &accountUuid) const { #ifdef Q_OS_LINUX // we can't use QStorageInfo as it does not list fuse mounts @@ -266,7 +274,7 @@ Result XattrVfsPluginFactory::prepare(const QString &path, const } } } else { - qCWarning(lcVfsXAttr) << "Failed to read /proc/self/mountinfo" << file.errorString(); + qCWarning(lcOpenVFS) << "Failed to read /proc/self/mountinfo" << file.errorString(); return tr("Failed to read /proc/self/mountinfo"); } } @@ -279,52 +287,46 @@ Result XattrVfsPluginFactory::prepare(const QString &path, const process.waitForFinished(); if (process.exitCode() != 0) { const auto output = process.readAll(); - qCWarning(lcVfsXAttr) << "Failed to unmount the OpenVFS mount" << path << output; + qCWarning(lcOpenVFS) << "Failed to unmount the OpenVFS mount" << path << output; return tr("Failed to unmount the OpenVFS mount %1 Error:%2").arg(path, output); } else { - qCDebug(lcVfsXAttr) << "Unmounted OpenVFS mount" << path; + qCDebug(lcOpenVFS) << "Unmounted OpenVFS mount" << path; } } #endif const auto fsPath = FileSystem::toFilesystemPath(path); if (!FileSystem::Xattr::supportsxattr(fsPath)) { - qCDebug(lcVfsXAttr) << path << "does not support xattributes"; + qCDebug(lcOpenVFS) << path << "does not support xattributes"; return tr("The filesystem for %1 does not support xattributes.").arg(path); } - if (const auto owner = FileSystem::Xattr::getxattr(fsPath, QString::fromUtf8(OpenVfsConstants::XAttributeNames::Owner))) { - if (accountUuid.isNull()) { - qCDebug(lcVfsXAttr) << path << "has an owner set" << owner << "Not our vfs!"; - return tr("The sync path is already claimed by a different account, please check your setup"); - } else if (owner != xattrOwnerString(accountUuid)) { - // owner is set. See if it is us - qCDebug(lcVfsXAttr) << path << "is claimed by a different account" << owner << "Not our vfs!"; - return tr("The sync path is claimed by a different cloud, please check your setup"); - } + if (const auto info = ::OpenVFS::RegistrationInfo::fromAttributes(fsPath); info && info.owner() != xattrOwnerString(accountUuid).toStdString()) { + return tr("The sync path is already claimed by %1").arg(info.owner()); } if (!openVFSExePath().exists()) { - qCDebug(lcVfsXAttr) << "OpenVFS executable not found at" << openVFSExePath().toString(); + qCDebug(lcOpenVFS) << "OpenVFS executable not found at" << openVFSExePath().toString(); return tr("OpenVFS executable not found, please install it"); } const auto vfsConfig = openVFSConfigFilePath(); if (!vfsConfig.get().empty()) { - qCDebug(lcVfsXAttr) << "Using config file" << vfsConfig.toString(); + qCDebug(lcOpenVFS) << "Using config file" << vfsConfig.toString(); } else { return tr("Failed to find the OpenVFS config file, please check your installation."); } return {}; } -OCC::Result VfsXAttr::updateMetadata(const SyncFileItem &syncItem, const QString &filePath, const QString &replacesFile) +OCC::Result OpenVFS::updateMetadata( + const SyncFileItem &syncItem, const QString &filePath, const QString &replacesFile) { if (syncItem._type == ItemTypeVirtualFileDehydration) { // replace the file with a placeholder if (const auto result = createPlaceholder(syncItem); !result) { - qCCritical(lcVfsXAttr) << "Failed to create placeholder for" << filePath << result.error(); + qCCritical(lcOpenVFS) << "Failed to create placeholder for" << filePath << result.error(); return result.error(); } return ConvertToPlaceholderResult::Ok; } else { - OpenVfsAttributes::PlaceHolderAttributes attributes = [&] { + ::OpenVFS::PlaceHolderAttributes attributes = [&] { // load the previous attributes if (!replacesFile.isEmpty()) { if (const auto attr = placeHolderAttributes(replacesFile)) { @@ -336,9 +338,9 @@ OCC::Result VfsXAttr::updateMetad } Q_ASSERT(QFileInfo::exists(filePath)); // generate new meta data for an existing file - auto attr = OpenVfsAttributes::PlaceHolderAttributes::create( + auto attr = ::OpenVFS::PlaceHolderAttributes::create( FileSystem::toFilesystemPath(filePath), syncItem._etag.toStdString(), syncItem._fileId.toStdString(), syncItem._size); - attr.state = OpenVfsConstants::States::Hydrated; + attr.state = ::OpenVFS::Constants::States::Hydrated; return attr; }(); Q_ASSERT(attributes); @@ -347,25 +349,25 @@ OCC::Result VfsXAttr::updateMetad attributes.fileId = syncItem._fileId.toStdString(); attributes.etag = syncItem._etag.toStdString(); - qCDebug(lcVfsXAttr) << attributes.absolutePath.native() << syncItem._type; + qCDebug(lcOpenVFS) << attributes.absolutePath.native() << syncItem._type; switch (syncItem._type) { case ItemTypeVirtualFileDownload: - attributes.state = OpenVfsConstants::States::Hydrating; + attributes.state = ::OpenVFS::Constants::States::Hydrating; break; case ItemTypeVirtualFile: [[fallthrough]]; case ItemTypeVirtualFileDehydration: - qCDebug(lcVfsXAttr) << "updateMetadata for virtual file " << syncItem._type; - attributes.state = OpenVfsConstants::States::DeHydrated; + qCDebug(lcOpenVFS) << "updateMetadata for virtual file " << syncItem._type; + attributes.state = ::OpenVFS::Constants::States::DeHydrated; break; case ItemTypeFile: // hydrated files must not have a size attribute != 0 attributes.size = 0; [[fallthrough]]; case ItemTypeDirectory: - qCDebug(lcVfsXAttr) << "updateMetadata for" << syncItem._type; - attributes.state = OpenVfsConstants::States::Hydrated; + qCDebug(lcOpenVFS) << "updateMetadata for" << syncItem._type; + attributes.state = ::OpenVFS::Constants::States::Hydrated; break; case ItemTypeSymLink: [[fallthrough]]; @@ -374,21 +376,21 @@ OCC::Result VfsXAttr::updateMetad } if (const auto result = setPlaceholderAttributes(attributes, syncItem._modtime); !result) { - qCCritical(lcVfsXAttr) << "Failed to update placeholder for" << filePath << result.error(); + qCCritical(lcOpenVFS) << "Failed to update placeholder for" << filePath << result.error(); return result.error(); } return ConvertToPlaceholderResult::Ok; } } -void VfsXAttr::slotHydrateJobFinished() +void OpenVFS::slotHydrateJobFinished() { - HydrationJob *hydration = qobject_cast(sender()); + HydrationJob *hydration = qobject_cast(sender()); const auto targetPath = FileSystem::toFilesystemPath(hydration->targetFileName()); Q_ASSERT(!targetPath.empty()); - qCInfo(lcVfsXAttr) << u"Hydration Job finished for" << targetPath.native(); + qCInfo(lcOpenVFS) << u"Hydration Job finished for" << targetPath.native(); if (std::filesystem::exists(targetPath)) { auto item = OCC::SyncFileItem::fromSyncJournalFileRecord(hydration->record()); @@ -398,24 +400,24 @@ void VfsXAttr::slotHydrateJobFinished() if (auto inode = FileSystem::getInode(targetPath)) { item->_inode = inode.value(); } else { - qCWarning(lcVfsXAttr) << u"Failed to get inode for" << targetPath.native(); + qCWarning(lcOpenVFS) << u"Failed to get inode for" << targetPath.native(); } // Update the client sync journal database if the file modifications have been successful const auto result = this->params().journal->setFileRecord(SyncJournalFileRecord::fromSyncFileItem(*item)); if (!result) { - qCWarning(lcVfsXAttr) << u"Error when setting the file record to the database" << result.error(); + qCWarning(lcOpenVFS) << u"Error when setting the file record to the database" << result.error(); } else { - qCInfo(lcVfsXAttr) << u"Hydration succeeded" << targetPath.native(); + qCInfo(lcOpenVFS) << u"Hydration succeeded" << targetPath.native(); } } else { - qCWarning(lcVfsXAttr) << u"Hydration succeeded but the file appears to be moved" << targetPath.native(); + qCWarning(lcOpenVFS) << u"Hydration succeeded but the file appears to be moved" << targetPath.native(); } hydration->deleteLater(); this->_hydrationJobs.remove(hydration->fileId()); } -Result VfsXAttr::createPlaceholder(const SyncFileItem &item) +Result OpenVFS::createPlaceholder(const SyncFileItem &item) { const auto path = params().root() / item.localName(); if (path.exists()) { @@ -431,35 +433,35 @@ Result VfsXAttr::createPlaceholder(const SyncFileItem &item) file.write(""); file.close(); - const auto attributes = OpenVfsAttributes::PlaceHolderAttributes::create(path, item._etag.toStdString(), item._fileId.toStdString(), item._size); + const auto attributes = ::OpenVFS::PlaceHolderAttributes::create(path, item._etag.toStdString(), item._fileId.toStdString(), item._size); return setPlaceholderAttributes(attributes, item._modtime); } -HydrationJob* VfsXAttr::hydrateFile(const QByteArray &fileId, const QString &targetPath) +HydrationJob *OpenVFS::hydrateFile(const QByteArray &fileId, const QString &targetPath) { - qCInfo(lcVfsXAttr) << u"Requesting hydration for" << fileId; + qCInfo(lcOpenVFS) << u"Requesting hydration for" << fileId; if (_hydrationJobs.contains(fileId)) { - qCWarning(lcVfsXAttr) << u"Ignoring hydration request for running hydration for fileId" << fileId; + qCWarning(lcOpenVFS) << u"Ignoring hydration request for running hydration for fileId" << fileId; return {}; } if (auto attr = placeHolderAttributes(targetPath)) { - attr.state = OpenVfsConstants::States::Hydrating; + attr.state = ::OpenVFS::Constants::States::Hydrating; if (auto res = setPlaceholderAttributes(attr); !res) { - qCWarning(lcVfsXAttr) << u"Failed to set attributes for" << targetPath << res.error(); + qCWarning(lcOpenVFS) << u"Failed to set attributes for" << targetPath << res.error(); return nullptr; } } else { - qCWarning(lcVfsXAttr) << u"Failed to get attributes for" << targetPath; + qCWarning(lcOpenVFS) << u"Failed to get attributes for" << targetPath; return nullptr; } HydrationJob *hydration = new HydrationJob(this, fileId, std::make_unique(targetPath), nullptr); hydration->setTargetFile(targetPath); _hydrationJobs.insert(fileId, hydration); - connect(hydration, &HydrationJob::finished, this, &VfsXAttr::slotHydrateJobFinished); + connect(hydration, &HydrationJob::finished, this, &OpenVFS::slotHydrateJobFinished); connect(hydration, &HydrationJob::error, this, [this, hydration](const QString &error) { - qCWarning(lcVfsXAttr) << u"Hydration failed" << error; + qCWarning(lcOpenVFS) << u"Hydration failed" << error; this->_hydrationJobs.remove(hydration->fileId()); hydration->deleteLater(); }); @@ -467,26 +469,26 @@ HydrationJob* VfsXAttr::hydrateFile(const QByteArray &fileId, const QString &tar return hydration; } -bool VfsXAttr::needsMetadataUpdate(const SyncFileItem &item) +bool OpenVFS::needsMetadataUpdate(const SyncFileItem &item) { const auto path = params().root() / item.localName(); // if the attributes do not exist we need to add them return QFileInfo::exists(path.toString()) && !placeHolderAttributes(path); } -bool VfsXAttr::isDehydratedPlaceholder(const QString &filePath) +bool OpenVFS::isDehydratedPlaceholder(const QString &filePath) { if (QFileInfo::exists(filePath)) { - return placeHolderAttributes(filePath).state == OpenVfsConstants::States::DeHydrated; + return placeHolderAttributes(filePath).state == ::OpenVFS::Constants::States::DeHydrated; } return false; } -LocalInfo VfsXAttr::statTypeVirtualFile(const std::filesystem::directory_entry &path, ItemType type) +LocalInfo OpenVFS::statTypeVirtualFile(const std::filesystem::directory_entry &path, ItemType type) { if (type == ItemTypeFile) { const auto attribs = placeHolderAttributes(path.path()); - if (attribs.state == OpenVfsConstants::States::DeHydrated) { + if (attribs.state == ::OpenVFS::Constants::States::DeHydrated) { type = ItemTypeVirtualFile; if (attribs.pinState == convertPinState(PinState::AlwaysLocal)) { type = ItemTypeVirtualFileDownload; @@ -497,14 +499,14 @@ LocalInfo VfsXAttr::statTypeVirtualFile(const std::filesystem::directory_entry & } } } - qCDebug(lcVfsXAttr) << path.path().native() << Utility::enumToString(type); + qCDebug(lcOpenVFS) << path.path().native() << Utility::enumToString(type); return LocalInfo(path, type); } -bool VfsXAttr::setPinState(const QString &folderPath, PinState state) +bool OpenVFS::setPinState(const QString &folderPath, PinState state) { const auto localPath = params().root() / folderPath; - qCDebug(lcVfsXAttr) << localPath.toString() << state; + qCDebug(lcOpenVFS) << localPath.toString() << state; auto attribs = placeHolderAttributes(localPath); if (!attribs) { // the file is not yet converted @@ -517,22 +519,22 @@ bool VfsXAttr::setPinState(const QString &folderPath, PinState state) return true; } -Optional VfsXAttr::pinState(const QString &folderPath) +Optional OpenVFS::pinState(const QString &folderPath) { for (auto relativePath = FileSystem::Path::relative(folderPath).get();; relativePath = relativePath.parent_path()) { const auto attributes = placeHolderAttributes(params().root() / relativePath); if (!attributes) { - qCDebug(lcVfsXAttr) << "Couldn't find pin state for placeholder file" << folderPath; + qCDebug(lcOpenVFS) << "Couldn't find pin state for placeholder file" << folderPath; return {}; } // if the state is inherited and we still have a parent path, retreive that instead. - if (attributes.pinState != OpenVfsConstants::PinStates::Inherited || !relativePath.has_relative_path()) { + if (attributes.pinState != ::OpenVFS::Constants::PinStates::Inherited || !relativePath.has_relative_path()) { return convertPinState(attributes.pinState); } } } -Vfs::AvailabilityResult VfsXAttr::availability(const QString &folderPath) +Vfs::AvailabilityResult OpenVFS::availability(const QString &folderPath) { const auto attribs = placeHolderAttributes(params().root() / folderPath); if (attribs) { @@ -543,11 +545,11 @@ Vfs::AvailabilityResult VfsXAttr::availability(const QString &folderPath) return VfsItemAvailability::OnlineOnly; case OCC::PinState::Inherited: { switch (attribs.state) { - case OpenVfsConstants::States::Hydrated: + case ::OpenVFS::Constants::States::Hydrated: return VfsItemAvailability::AllHydrated; - case OpenVfsConstants::States::DeHydrated: + case ::OpenVFS::Constants::States::DeHydrated: return VfsItemAvailability::AllDehydrated; - case OpenVfsConstants::States::Hydrating: + case ::OpenVFS::Constants::States::Hydrating: return VfsItemAvailability::Mixed; } } @@ -563,14 +565,14 @@ Vfs::AvailabilityResult VfsXAttr::availability(const QString &folderPath) return VfsItemAvailability::Mixed; } -void VfsXAttr::fileStatusChanged(const QString& systemFileName, SyncFileStatus fileStatus) +void OpenVFS::fileStatusChanged(const QString &systemFileName, SyncFileStatus fileStatus) { if (fileStatus.tag() == SyncFileStatus::StatusExcluded) { const FileSystem::Path rel = FileSystem::Path(systemFileName)->lexically_relative(params().root()); setPinState(rel.toString(), PinState::Excluded); return; } - qCDebug(lcVfsXAttr) << systemFileName << fileStatus; + qCDebug(lcOpenVFS) << systemFileName << fileStatus; } diff --git a/src/plugins/vfs/xattr/vfs_xattr.h b/src/plugins/vfs/openvfs/vfs_openvfs.h similarity index 87% rename from src/plugins/vfs/xattr/vfs_xattr.h rename to src/plugins/vfs/openvfs/vfs_openvfs.h index 07e0a5381..5595124d9 100644 --- a/src/plugins/vfs/xattr/vfs_xattr.h +++ b/src/plugins/vfs/openvfs/vfs_openvfs.h @@ -11,9 +11,9 @@ #include #include -#include "vfs/vfs.h" #include "common/plugin.h" #include "common/result.h" +#include "vfs/vfs.h" #include @@ -21,13 +21,13 @@ namespace OCC { class HydrationJob; -class VfsXAttr : public Vfs +class OpenVFS : public Vfs { Q_OBJECT public: - explicit VfsXAttr(QObject *parent = nullptr); - ~VfsXAttr() override; + explicit OpenVFS(QObject *parent = nullptr); + ~OpenVFS() override; [[nodiscard]] Mode mode() const override; @@ -49,7 +49,7 @@ class VfsXAttr : public Vfs Optional pinState(const QString &folderPath) override; AvailabilityResult availability(const QString &folderPath) override; - HydrationJob* hydrateFile(const QByteArray &fileId, const QString& targetPath) override; + HydrationJob *hydrateFile(const QByteArray &fileId, const QString &targetPath) override; Q_SIGNALS: void finished(Result); @@ -63,11 +63,11 @@ public Q_SLOTS: void startImpl(const VfsSetupParams ¶ms) override; private: - QMap _hydrationJobs; + QMap _hydrationJobs; QPointer _openVfsProcess; }; -class XattrVfsPluginFactory : public QObject, public DefaultPluginFactory +class OpenVfsPluginFactory : public QObject, public DefaultPluginFactory { Q_OBJECT Q_PLUGIN_METADATA(IID "eu.opencloud.PluginFactory" FILE "libsync/vfs/vfspluginmetadata.json") diff --git a/test/testblacklist.cpp b/test/testblacklist.cpp index a6de4afe3..0257a614f 100644 --- a/test/testblacklist.cpp +++ b/test/testblacklist.cpp @@ -28,9 +28,9 @@ private Q_SLOTS: QTest::newRow("Vfs::Mode::Off") << Vfs::Mode::Off << false; - if (VfsPluginManager::instance().isVfsPluginAvailable(Vfs::Mode::XAttr)) { - QTest::newRow("Vfs::Mode::Xattr dehydrdeated") << Vfs::Mode::XAttr << false; - QTest::newRow("Vfs::Mode::Xattr hydrated") << Vfs::Mode::XAttr << true; + if (VfsPluginManager::instance().isVfsPluginAvailable(Vfs::Mode::OpenVFS)) { + QTest::newRow("Vfs::Mode::Xattr dehydrdeated") << Vfs::Mode::OpenVFS << false; + QTest::newRow("Vfs::Mode::Xattr hydrated") << Vfs::Mode::OpenVFS << true; } if (VfsPluginManager::instance().isVfsPluginAvailable(Vfs::Mode::WindowsCfApi)) { diff --git a/test/testdatabaseerror.cpp b/test/testdatabaseerror.cpp index 7a6c98237..6f022a516 100644 --- a/test/testdatabaseerror.cpp +++ b/test/testdatabaseerror.cpp @@ -24,9 +24,9 @@ private Q_SLOTS: QTest::newRow("Vfs::Mode::Off") << Vfs::Mode::Off << false; - if (VfsPluginManager::instance().isVfsPluginAvailable(Vfs::Mode::XAttr)) { - QTest::newRow("Vfs::Mode::Xattr dehydrdeated") << Vfs::Mode::XAttr << false; - QTest::newRow("Vfs::Mode::Xattr hydrated") << Vfs::Mode::XAttr << true; + if (VfsPluginManager::instance().isVfsPluginAvailable(Vfs::Mode::OpenVFS)) { + QTest::newRow("Vfs::Mode::Xattr dehydrdeated") << Vfs::Mode::OpenVFS << false; + QTest::newRow("Vfs::Mode::Xattr hydrated") << Vfs::Mode::OpenVFS << true; } if (VfsPluginManager::instance().isVfsPluginAvailable(Vfs::Mode::WindowsCfApi)) { diff --git a/test/testdownload.cpp b/test/testdownload.cpp index 84e73703f..1e4996ee4 100644 --- a/test/testdownload.cpp +++ b/test/testdownload.cpp @@ -73,9 +73,9 @@ private Q_SLOTS: QTest::newRow("Vfs::Mode::Off") << Vfs::Mode::Off << false; - if (VfsPluginManager::instance().isVfsPluginAvailable(Vfs::Mode::XAttr)) { - QTest::newRow("Vfs::Mode::Xattr dehydrdeated") << Vfs::Mode::XAttr << false; - QTest::newRow("Vfs::Mode::Xattr hydrated") << Vfs::Mode::XAttr << true; + if (VfsPluginManager::instance().isVfsPluginAvailable(Vfs::Mode::OpenVFS)) { + QTest::newRow("Vfs::Mode::Xattr dehydrdeated") << Vfs::Mode::OpenVFS << false; + QTest::newRow("Vfs::Mode::Xattr hydrated") << Vfs::Mode::OpenVFS << true; } if (VfsPluginManager::instance().isVfsPluginAvailable(Vfs::Mode::WindowsCfApi)) {