Fix files not unlocking after lock time expired

Signed-off-by: Claudio Cambra <claudio.cambra@gmail.com>
This commit is contained in:
Claudio Cambra 2022-09-20 23:03:39 +02:00 committed by Matthieu Gallien
parent 311469a0e5
commit fd332a52e2
5 changed files with 49 additions and 11 deletions

View file

@ -1351,7 +1351,7 @@ bool SyncJournalDb::updateFileRecordChecksum(const QString &filename,
}
bool SyncJournalDb::updateLocalMetadata(const QString &filename,
qint64 modtime, qint64 size, quint64 inode)
qint64 modtime, qint64 size, quint64 inode, const SyncJournalFileLockInfo &lockInfo)
{
QMutexLocker locker(&_mutex);
@ -1365,7 +1365,9 @@ bool SyncJournalDb::updateLocalMetadata(const QString &filename,
}
const auto query = _queryManager.get(PreparedSqlQueryManager::SetFileRecordLocalMetadataQuery, QByteArrayLiteral("UPDATE metadata"
" SET inode=?2, modtime=?3, filesize=?4"
" SET inode=?2, modtime=?3, filesize=?4, lock=?5, lockType=?6,"
" lockOwnerDisplayName=?7, lockOwnerId=?8, lockOwnerEditor = ?9,"
" lockTime=?10, lockTimeout=?11"
" WHERE phash == ?1;"),
_db);
if (!query) {
@ -1376,6 +1378,13 @@ bool SyncJournalDb::updateLocalMetadata(const QString &filename,
query->bindValue(2, inode);
query->bindValue(3, modtime);
query->bindValue(4, size);
query->bindValue(5, lockInfo._locked ? 1 : 0);
query->bindValue(6, lockInfo._lockOwnerDisplayName);
query->bindValue(7, lockInfo._lockOwnerId);
query->bindValue(8, lockInfo._lockOwnerType);
query->bindValue(9, lockInfo._lockEditorApp);
query->bindValue(10, lockInfo._lockTime);
query->bindValue(11, lockInfo._lockTimeout);
return query->exec();
}

View file

@ -78,7 +78,7 @@ public:
const QByteArray &contentChecksum,
const QByteArray &contentChecksumType);
[[nodiscard]] bool updateLocalMetadata(const QString &filename,
qint64 modtime, qint64 size, quint64 inode);
qint64 modtime, qint64 size, quint64 inode, const SyncJournalFileLockInfo &lockInfo);
/// Return value for hasHydratedOrDehydratedFiles()
struct HasHydratedDehydrated

View file

@ -394,6 +394,17 @@ void ProcessDirectoryJob::processFile(PathTuple path,
if (item->_type == ItemTypeVirtualFileDehydration)
item->_type = ItemTypeFile;
// We want to check the lock state of this file after the lock time has expired
if(serverEntry.locked == SyncFileItem::LockStatus::LockedItem) {
const auto lockExpirationTime = serverEntry.lockTime + serverEntry.lockTimeout;
const auto timeRemaining = QDateTime::currentDateTime().secsTo(QDateTime::fromSecsSinceEpoch(lockExpirationTime));
const auto timerInterval = qMax(5LL, timeRemaining);
qCInfo(lcDisco) << "Will re-check lock status for:" << path._original << "in:" << timerInterval << "seconds.";
_discoveryData->_anotherSyncNeeded = true;
_discoveryData->_scheduleSyncInSecs = timerInterval;
}
// VFS suffixed files on the server are ignored
if (isVfsWithSuffix()) {
if (hasVirtualFileSuffix(serverEntry.name)
@ -505,6 +516,7 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
const bool isVirtualE2EePlaceholder = isDbEntryAnE2EePlaceholder && serverEntry.size >= Constants::e2EeTagSize;
const qint64 sizeOnServer = isVirtualE2EePlaceholder ? serverEntry.size - Constants::e2EeTagSize : serverEntry.size;
const bool metaDataSizeNeedsUpdateForE2EeFilePlaceholder = isVirtualE2EePlaceholder && dbEntry._fileSize == serverEntry.size;
const bool serverEntryLockedAsBool = serverEntry.locked == SyncFileItem::LockStatus::LockedItem;
if (serverEntry.isDirectory != dbEntry.isDirectory()) {
// If the type of the entity changed, it's like NEW, but
@ -551,6 +563,8 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
}
item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
item->_direction = SyncFileItem::Down;
} else if(serverEntryLockedAsBool != dbEntry._lockstate._locked) {
item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
} else {
// if (is virtual mode enabled and folder is encrypted - check if the size is the same as on the server and then - trigger server query
// to update a placeholder with corrected size (-16 Bytes)

View file

@ -283,6 +283,7 @@ public:
// output
QByteArray _dataFingerprint;
bool _anotherSyncNeeded = false;
int _scheduleSyncInSecs = -1;
signals:
void fatalError(const QString &errorString);

View file

@ -391,7 +391,17 @@ void OCC::SyncEngine::slotItemDiscovered(const OCC::SyncFileItemPtr &item)
emit itemCompleted(item);
} else {
// Update only outdated data from the disk.
if (!_journal->updateLocalMetadata(item->_file, item->_modtime, item->_size, item->_inode)) {
SyncJournalFileLockInfo lockInfo;
lockInfo._locked = item->_locked == SyncFileItem::LockStatus::LockedItem;
lockInfo._lockTime = item->_lockTime;
lockInfo._lockTimeout = item->_lockTimeout;
lockInfo._lockOwnerId = item->_lockOwnerId;
lockInfo._lockOwnerType = static_cast<qint64>(item->_lockOwnerType);
lockInfo._lockOwnerDisplayName = item->_lockOwnerDisplayName;
lockInfo._lockEditorApp = item->_lockOwnerDisplayName;
if (!_journal->updateLocalMetadata(item->_file, item->_modtime, item->_size, item->_inode, lockInfo)) {
qCWarning(lcEngine) << "Could not update local metadata for file" << item->_file;
}
}
@ -689,7 +699,11 @@ void SyncEngine::slotDiscoveryFinished()
restoreOldFiles(_syncItems);
}
if (_discoveryPhase->_anotherSyncNeeded && _anotherSyncNeeded == NoFollowUpSync) {
if (_discoveryPhase->_anotherSyncNeeded && _discoveryPhase->_scheduleSyncInSecs > 0) {
QTimer::singleShot(_discoveryPhase->_scheduleSyncInSecs * 1000, this, [this]{
this->startSync();
});
} else if (_discoveryPhase->_anotherSyncNeeded && _anotherSyncNeeded == NoFollowUpSync) {
_anotherSyncNeeded = ImmediateFollowUp;
}