Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/libsync/path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,8 @@ bool OCC::FileSystem::Path::exists() const
}
return exists;
}

QDebug operator<<(QDebug debug, const OCC::FileSystem::Path &path)
{
return debug << u"Path(" << path.toString() << u")";
}
3 changes: 3 additions & 0 deletions src/libsync/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,6 @@ namespace FileSystem {
};
}
}


OPENCLOUD_SYNC_EXPORT QDebug operator<<(QDebug debug, const OCC::FileSystem::Path &path);
34 changes: 20 additions & 14 deletions src/plugins/vfs/cfapi/cfapiwrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,13 +476,24 @@ OCC::Result<void, QString> OCC::CfApiWrapper::disconnectSyncRoot(CF_CONNECTION_K
return {};
}
}


bool OCC::CfApiWrapper::isSparseFile(const QString &path)
bool OCC::CfApiWrapper::isDehydratedPlaceholder(const FileSystem::Path &path)
{
const auto p = path.toStdWString();
const auto attributes = GetFileAttributes(p.data());
return (attributes & FILE_ATTRIBUTE_SPARSE_FILE) != 0;
const auto handle = OCC::Utility::Handle::createHandle(path);
if (!handle) {
qCWarning(lcCfApiWrapper) << u"Failed to get file handle" << path << handle.errorMessage();
return false;
}
FILE_ATTRIBUTE_TAG_INFO targInfo = {};
if (!GetFileInformationByHandleEx(handle, FileAttributeTagInfo, &targInfo, sizeof(targInfo))) {
const auto error = GetLastError();
qCWarning(lcCfApiWrapper) << u"Failed to get file attribute tag info for" << path << OCC::Utility::formatWinError(error);
return false;
}
const CF_PLACEHOLDER_STATE state = CfGetPlaceholderStateFromAttributeTag(targInfo.FileAttributes, targInfo.ReparseTag);
if (state == CF_PLACEHOLDER_STATE_NO_STATES) {
return false;
}
return state & CF_PLACEHOLDER_STATE_PARTIAL;
}

template <>
Expand Down Expand Up @@ -575,17 +586,12 @@ OCC::Result<OCC::Vfs::ConvertToPlaceholderResult, QString> OCC::CfApiWrapper::up
return updatePlaceholderState(path, modtime, size, fileId, replacesPath);
}

OCC::Result<OCC::Vfs::ConvertToPlaceholderResult, QString> OCC::CfApiWrapper::dehydratePlaceholder(const QString &path, qint64 size, const QByteArray &fileId)
OCC::Result<OCC::Vfs::ConvertToPlaceholderResult, QString> OCC::CfApiWrapper::dehydratePlaceholder(const QString &path, const QByteArray &fileId)
{
const auto info = findPlaceholderInfo<CF_PLACEHOLDER_BASIC_INFO>(path);
if (info) {
setPinState(path, OCC::PinState::OnlineOnly, OCC::CfApiWrapper::NoRecurse);

CF_FILE_RANGE dehydrationRange = {};
dehydrationRange.Length.QuadPart = size;

const qint64 result = CfUpdatePlaceholder(Utility::Handle::createHandle(OCC::FileSystem::toFilesystemPath(path)), nullptr, fileId.data(),
static_cast<DWORD>(fileId.size()), &dehydrationRange, 1, CF_UPDATE_FLAG_MARK_IN_SYNC | CF_UPDATE_FLAG_DEHYDRATE, nullptr, nullptr);
static_cast<DWORD>(fileId.size()), nullptr, 0, CF_UPDATE_FLAG_MARK_IN_SYNC | CF_UPDATE_FLAG_DEHYDRATE, nullptr, nullptr);
if (result != S_OK) {
const auto errorMessage = createErrorMessageForPlaceholderUpdateAndCreate(path, u"Couldn't update placeholder info"_s);
qCWarning(lcCfApiWrapper) << errorMessage << path << u":" << OCC::Utility::formatWinError(result);
Expand All @@ -600,8 +606,8 @@ OCC::Result<OCC::Vfs::ConvertToPlaceholderResult, QString> OCC::CfApiWrapper::de
qCWarning(lcCfApiWrapper) << errorMessage << path << u":" << OCC::Utility::formatWinError(result);
return errorMessage;
}
setPinState(path, OCC::PinState::OnlineOnly, OCC::CfApiWrapper::NoRecurse);
}

return OCC::Vfs::ConvertToPlaceholderResult::Ok;
}

Expand Down
4 changes: 2 additions & 2 deletions src/plugins/vfs/cfapi/cfapiwrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ namespace CfApiWrapper {
Result<CF_CONNECTION_KEY, QString> connectSyncRoot(const QString &path, VfsCfApi *context);
Result<void, QString> disconnectSyncRoot(CF_CONNECTION_KEY &&key);

bool isSparseFile(const QString &path);
bool isDehydratedPlaceholder(const FileSystem::Path &path);

/**
* The placeholder info can have a dynamic size, by default we don't query FileIdentity
Expand All @@ -123,7 +123,7 @@ namespace CfApiWrapper {
const QString &path, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath = QString());
Result<OCC::Vfs::ConvertToPlaceholderResult, QString> convertToPlaceholder(
const QString &path, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath);
Result<OCC::Vfs::ConvertToPlaceholderResult, QString> dehydratePlaceholder(const QString &path, qint64 size, const QByteArray &fileId);
Result<OCC::Vfs::ConvertToPlaceholderResult, QString> dehydratePlaceholder(const QString &path, const QByteArray &fileId);
Result<OCC::Vfs::ConvertToPlaceholderResult, QString> updatePlaceholderMarkInSync(const Utility::Handle &handle);
bool isPlaceHolderInSync(const QString &filePath);
}
Expand Down
19 changes: 11 additions & 8 deletions src/plugins/vfs/cfapi/vfs_cfapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ void VfsCfApi::startImpl(const VfsSetupParams &params)
});
}

Result<void, QString> CfApiVfsPluginFactory::prepare(const QString &path, const QUuid &accountUuid) const
Result<void, QString> CfApiVfsPluginFactory::prepare(const QString &path, const QUuid &) const
{
if (QDir(path).isRoot()) {
return tr("The Virtual filesystem feature does not support a drive as sync root");
Expand Down Expand Up @@ -185,7 +185,10 @@ Result<Vfs::ConvertToPlaceholderResult, QString> VfsCfApi::updateMetadata(const
const auto replacesPath = QDir::toNativeSeparators(replacesFile);

if (syncItem._type == ItemTypeVirtualFileDehydration) {
return cfapi::dehydratePlaceholder(localPath, syncItem._size, syncItem._fileId);
auto result = cfapi::dehydratePlaceholder(localPath, syncItem._fileId);
// if the dehydration call succeeded, check whether the placeholder is dehydrated
Q_ASSERT(!result || isDehydratedPlaceholder(filePath));
return result;
} else {
if (cfapi::findPlaceholderInfo<CF_PLACEHOLDER_BASIC_INFO>(localPath)) {
return cfapi::updatePlaceholderInfo(localPath, syncItem._modtime, syncItem._size, syncItem._fileId, replacesPath);
Expand Down Expand Up @@ -213,20 +216,20 @@ bool VfsCfApi::needsMetadataUpdate(const SyncFileItem &item)

bool VfsCfApi::isDehydratedPlaceholder(const QString &filePath)
{
const auto path = QDir::toNativeSeparators(filePath);
return cfapi::isSparseFile(path);
return cfapi::isDehydratedPlaceholder(FileSystem::Path(filePath));
}

LocalInfo VfsCfApi::statTypeVirtualFile(const std::filesystem::directory_entry &path, ItemType type)
LocalInfo VfsCfApi::statTypeVirtualFile(const std::filesystem::directory_entry &entry, ItemType type)
{
// only get placeholder info if it's a file
if (type == ItemTypeFile) {
if (auto placeholderInfo = cfapi::findPlaceholderInfo<CF_PLACEHOLDER_BASIC_INFO>(FileSystem::fromFilesystemPath(path))) {
const auto path = FileSystem::Path(entry);
if (auto placeholderInfo = cfapi::findPlaceholderInfo<CF_PLACEHOLDER_BASIC_INFO>(path.toString())) {
Q_ASSERT(placeholderInfo.handle());
FILE_ATTRIBUTE_TAG_INFO attributeInfo = {};
if (!GetFileInformationByHandleEx(placeholderInfo.handle(), FileAttributeTagInfo, &attributeInfo, sizeof(attributeInfo))) {
const auto error = GetLastError();
qCCritical(lcCfApi) << u"GetFileInformationByHandle failed on" << path.path() << OCC::Utility::formatWinError(error);
qCCritical(lcCfApi) << u"GetFileInformationByHandle failed on" << path << OCC::Utility::formatWinError(error);
return {};
}
const CF_PLACEHOLDER_STATE placeholderState = CfGetPlaceholderStateFromAttributeTag(attributeInfo.FileAttributes, attributeInfo.ReparseTag);
Expand All @@ -250,7 +253,7 @@ LocalInfo VfsCfApi::statTypeVirtualFile(const std::filesystem::directory_entry &
}
}
}
return LocalInfo(path, type);
return LocalInfo(entry, type);
}

bool VfsCfApi::setPinState(const QString &folderPath, PinState state)
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/vfs/cfapi/vfs_cfapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class VfsCfApi : public Vfs

void cancelHydration(const OCC::CfApiWrapper::CallBackContext &context);

LocalInfo statTypeVirtualFile(const std::filesystem::directory_entry &path, ItemType type) override;
LocalInfo statTypeVirtualFile(const std::filesystem::directory_entry &entry, ItemType type) override;

public Q_SLOTS:
void fileStatusChanged(const QString &systemFileName, OCC::SyncFileStatus fileStatus) override;
Expand Down
10 changes: 5 additions & 5 deletions src/plugins/vfs/xattr/vfs_xattr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ OpenVfsAttributes::PlaceHolderAttributes placeHolderAttributes(const std::filesy
{
const auto data = OCC::FileSystem::Xattr::getxattr(path, QString::fromUtf8(OpenVfsConstants::XAttributeNames::Data));
if (!data) {
qCWarning(lcVfsXAttr) << "No OpenVFS xattr found for" << path;
qCWarning(lcVfsXAttr) << u"No OpenVFS xattr found for" << path.native();
}
return OpenVfsAttributes::PlaceHolderAttributes::fromData(path, data ? std::vector<uint8_t>{data->cbegin(), data->cend()} : std::vector<uint8_t>{});
}
Expand Down Expand Up @@ -388,7 +388,7 @@ void VfsXAttr::slotHydrateJobFinished()
const auto targetPath = FileSystem::toFilesystemPath(hydration->targetFileName());
Q_ASSERT(!targetPath.empty());

qCInfo(lcVfsXAttr) << u"Hydration Job finished for" << targetPath;
qCInfo(lcVfsXAttr) << u"Hydration Job finished for" << targetPath.native();

if (std::filesystem::exists(targetPath)) {
auto item = OCC::SyncFileItem::fromSyncJournalFileRecord(hydration->record());
Expand All @@ -398,17 +398,17 @@ void VfsXAttr::slotHydrateJobFinished()
if (auto inode = FileSystem::getInode(targetPath)) {
item->_inode = inode.value();
} else {
qCWarning(lcVfsXAttr) << u"Failed to get inode for" << targetPath;
qCWarning(lcVfsXAttr) << 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();
} else {
qCInfo(lcVfsXAttr) << u"Hydration succeeded" << targetPath;
qCInfo(lcVfsXAttr) << u"Hydration succeeded" << targetPath.native();
}
} else {
qCWarning(lcVfsXAttr) << u"Hydration succeeded but the file appears to be moved" << targetPath;
qCWarning(lcVfsXAttr) << u"Hydration succeeded but the file appears to be moved" << targetPath.native();
}

hydration->deleteLater();
Expand Down
2 changes: 1 addition & 1 deletion test/testutility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ private Q_SLOTS:
if (SUCCEEDED(hres)) {
hres = ppf->Save(target.native().data(), true);
if (SUCCEEDED(hres)) {
qDebug() << u"Created lnk" << target << u"->" << path;
qDebug() << u"Created lnk" << target.native() << u"->" << path;
} else {
qCritical() << u"Failed to create lnk: Save" << OCC::Utility::formatWinError(hres);
}
Expand Down