Folder: Ignore change from the watcher if the file has not changed its mtime or size...
authorOlivier Goffart <olivier@woboq.com>
Fri, 3 Jun 2016 11:06:11 +0000 (13:06 +0200)
committerMarkus Goetz <markus@woboq.com>
Fri, 3 Jun 2016 11:06:11 +0000 (13:06 +0200)
For issue #4927:
On Windows 10, we get a notification after the sync is finished for file that were
just downloaded. The guard we have against our "own changes" are only working when
the sync is running and the OwncloudPropagator still alive.

src/gui/folder.cpp

index 3b36ca48be5ba35fa8327679589405deadbef07b..518859fe4748bb03a6565c75b52a8e4918c69ba7 100644 (file)
@@ -579,19 +579,10 @@ int Folder::slotWipeErrorBlacklist()
 
 void Folder::slotWatchedPathChanged(const QString& path)
 {
-    // When no sync is running or it's in the prepare phase, we can
-    // always schedule a new sync.
-    if (! _engine->isSyncRunning() || _syncResult.status() == SyncResult::SyncPrepare) {
-        emit watchedFileChangedExternally(path);
-        emit scheduleToSync(this);
-        return;
-    }
-
     // The folder watcher fires a lot of bogus notifications during
     // a sync operation, both for actual user files and the database
     // and log. Therefore we check notifications against operations
     // the sync is doing to filter out our own changes.
-    bool ownChange = false;
 #ifdef Q_OS_MAC
     Q_UNUSED(path)
     // On OSX the folder watcher does not report changes done by our
@@ -601,14 +592,23 @@ void Folder::slotWatchedPathChanged(const QString& path)
     const auto maxNotificationDelay = 15*1000;
     qint64 time = _engine->timeSinceFileTouched(path);
     if (time != -1 && time < maxNotificationDelay) {
-        ownChange = true;
+        return;
     }
 #endif
 
-    if (! ownChange) {
-        emit watchedFileChangedExternally(path);
-        emit scheduleToSync(this);
+    // Check that the mtime actually changed.
+    if (path.startsWith(this->path())) {
+        auto relativePath = path.mid(this->path().size());
+        auto record = _journal.getFileRecord(relativePath);
+        if (record.isValid() && !FileSystem::fileChanged(path, record._fileSize,
+                Utility::qDateTimeToTime_t(record._modtime))) {
+            qDebug() << "Ignoring spurious notification for file" << relativePath;
+            return;  // probably a spurious notification
+        }
     }
+
+    emit watchedFileChangedExternally(path);
+    emit scheduleToSync(this);
 }
 
 void Folder::slotThreadTreeWalkResult(const SyncFileItemVector& items)