Merge pull request #7477 from nextcloud/bugfix/readOnlyVirtualFilesFixes

Improve read only virtual files support on Windows
This commit is contained in:
Matthieu Gallien 2024-11-22 10:06:19 +01:00 committed by GitHub
commit f1c6b65265
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 40 additions and 17 deletions

View File

@ -131,6 +131,7 @@ void FileSystem::setFileReadOnly(const QString &filename, bool readonly)
{
qCWarning(lcFileSystem()) << filename << (readonly ? "readonly" : "read write") << e.what();
}
return;
}
#endif
QFile file(filename);

View File

@ -275,9 +275,9 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
case DisplayPathRole:
return getDisplayPath();
case PathRole:
return QFileInfo(getFilePath()).path();
return getFilePath();
case OpenablePathRole:
return a._isMultiObjectActivity ? QFileInfo(getFilePath()).canonicalPath() : QFileInfo(getFilePath()).canonicalFilePath();
return getFilePath();
case DisplayLocationRole:
return displayLocation();
case ActionsLinksRole: {

View File

@ -1193,11 +1193,7 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
item->_direction = SyncFileItem::Down;
item->_instruction = CSYNC_INSTRUCTION_SYNC;
const auto pinState = _discoveryData->_syncOptions._vfs->pinState(path._local);
if (FileSystem::isLnkFile(path._local) && !_discoveryData->_syncOptions._vfs->pinState(path._local).isValid()) {
item->_type = ItemTypeVirtualFileDownload;
} else {
item->_type = ItemTypeVirtualFileDehydration;
}
item->_type = ItemTypeVirtualFileDehydration;
} else if (!serverModified
&& (dbEntry._inode != localEntry.inode
|| (localEntry.isMetadataMissing && item->_type == ItemTypeFile && !FileSystem::isLnkFile(item->_file))
@ -1735,6 +1731,15 @@ void ProcessDirectoryJob::processFileFinalize(
item->_instruction = CSyncEnums::CSYNC_INSTRUCTION_UPDATE_VFS_METADATA;
}
if (_discoveryData->_syncOptions._vfs &&
(item->_type == CSyncEnums::ItemTypeFile || item->_type == CSyncEnums::ItemTypeDirectory) &&
item->_instruction == CSyncEnums::CSYNC_INSTRUCTION_NONE &&
FileSystem::isLnkFile((_discoveryData->_localDir + path._local))) {
item->_instruction = CSyncEnums::CSYNC_INSTRUCTION_SYNC;
item->_direction = SyncFileItem::Down;
item->_type = CSyncEnums::ItemTypeVirtualFileDehydration;
}
if (path._original != path._target && (item->_instruction == CSYNC_INSTRUCTION_UPDATE_VFS_METADATA || item->_instruction == CSYNC_INSTRUCTION_UPDATE_METADATA || item->_instruction == CSYNC_INSTRUCTION_NONE)) {
ASSERT(_dirItem && _dirItem->_instruction == CSYNC_INSTRUCTION_RENAME);
// This is because otherwise subitems are not updated! (ideally renaming a directory could

View File

@ -498,6 +498,13 @@ void PropagateDownloadFile::startAfterIsEncryptedIsChecked()
}
qCDebug(lcPropagateDownload) << "dehydrating file" << _item->_file;
if (FileSystem::isLnkFile(fsPath)) {
const auto convertResult = vfs->convertToPlaceholder(fsPath, *_item);
if (!convertResult) {
qCCritical(lcPropagateDownload()) << "error when converting a shortcut file to placeholder" << convertResult.error();
}
}
auto r = vfs->dehydratePlaceholder(*_item);
if (!r) {
done(SyncFileItem::NormalError, r.error(), ErrorCategory::GenericError);

View File

@ -117,7 +117,8 @@ void PropagateLocalRemove::start()
}
QString removeError;
if (_moveToTrash) {
const auto availability = propagator()->syncOptions()._vfs->availability(_item->_file, Vfs::AvailabilityRecursivity::RecursiveAvailability);
if (_moveToTrash && (!availability || (*availability != VfsItemAvailability::AllDehydrated && *availability != VfsItemAvailability::OnlineOnly && *availability != VfsItemAvailability::Mixed))) {
if ((QDir(filename).exists() || FileSystem::fileExists(filename))
&& !FileSystem::moveToTrash(filename, &removeError)) {
done(SyncFileItem::NormalError, removeError, ErrorCategory::GenericError);
@ -228,8 +229,6 @@ void PropagateLocalMkdir::startLocalMkdir()
#if !defined(Q_OS_MACOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_15
if (!_item->_remotePerm.isNull() &&
!_item->_remotePerm.hasPermission(RemotePermissions::CanAddFile) &&
!_item->_remotePerm.hasPermission(RemotePermissions::CanRename) &&
!_item->_remotePerm.hasPermission(RemotePermissions::CanMove) &&
!_item->_remotePerm.hasPermission(RemotePermissions::CanAddSubDirectories)) {
try {
FileSystem::setFolderPermissions(newDirStr, FileSystem::FolderPermissions::ReadOnly);

View File

@ -157,17 +157,17 @@ void CALLBACK cfApiFetchDataCallback(const CF_CALLBACK_INFO *callbackInfo, const
callbackInfo->FileSize.QuadPart);
};
if (QCoreApplication::applicationPid() == callbackInfo->ProcessInfo->ProcessId) {
qCCritical(lcCfApiWrapper) << "implicit hydration triggered by the client itself. Will lead to a deadlock. Cancel";
sendTransferError();
return;
}
auto vfs = reinterpret_cast<OCC::VfsCfApi *>(callbackInfo->CallbackContext);
Q_ASSERT(vfs->metaObject()->className() == QByteArrayLiteral("OCC::VfsCfApi"));
const auto path = QString(QString::fromWCharArray(callbackInfo->VolumeDosName) + QString::fromWCharArray(callbackInfo->NormalizedPath));
const auto requestId = QString::number(callbackInfo->TransferKey.QuadPart, 16);
if (QCoreApplication::applicationPid() == callbackInfo->ProcessInfo->ProcessId) {
qCCritical(lcCfApiWrapper) << "implicit hydration triggered by the client itself. Will lead to a deadlock. Cancel" << path << requestId;
sendTransferError();
return;
}
qCDebug(lcCfApiWrapper) << "Request hydration for" << path << requestId;
const auto invokeResult = QMetaObject::invokeMethod(vfs, [=] { vfs->requestHydration(requestId, path); }, Qt::QueuedConnection);
@ -781,10 +781,12 @@ bool OCC::CfApiWrapper::isSparseFile(const QString &path)
OCC::CfApiWrapper::FileHandle OCC::CfApiWrapper::handleForPath(const QString &path)
{
if (path.isEmpty()) {
qCWarning(lcCfApiWrapper) << "empty path";
return {};
}
if (!FileSystem::fileExists(path)) {
qCWarning(lcCfApiWrapper) << "file does not exist";
return {};
}
@ -807,6 +809,7 @@ OCC::CfApiWrapper::FileHandle OCC::CfApiWrapper::handleForPath(const QString &pa
}
}
qCWarning(lcCfApiWrapper) << "no handle was created";
return {};
}

View File

@ -372,6 +372,14 @@ Vfs::AvailabilityResult VfsCfApi::availability(const QString &folderPath, const
return VfsItemAvailability::AlwaysLocal;
else
return VfsItemAvailability::AllHydrated;
} else {
if (pin && *pin == PinState::OnlineOnly) {
return VfsItemAvailability::OnlineOnly;
} else if (pin && *pin == PinState::AlwaysLocal) {
return VfsItemAvailability::AlwaysLocal;
} else {
return VfsItemAvailability::AllDehydrated;
}
}
return AvailabilityError::NoSuchItem;
}
@ -511,7 +519,7 @@ int VfsCfApi::finalizeHydrationJob(const QString &requestId)
VfsCfApi::HydratationAndPinStates VfsCfApi::computeRecursiveHydrationAndPinStates(const QString &folderPath, const Optional<PinState> &basePinState)
{
Q_ASSERT(!folderPath.endsWith('/'));
const auto fullPath = params().filesystemPath + folderPath;
const auto fullPath = QString{params().filesystemPath + folderPath};
QFileInfo info(params().filesystemPath + folderPath);
if (!FileSystem::fileExists(fullPath)) {