[tracker-miners/wip/carlosg/fanotify-fix] libtracker-miner: Handle FAN_DELETE[_SELF] being emitted separately on dirs




commit 2d230e6f96787214a78d92bfb28d813899a4dd74
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sun Mar 6 18:50:16 2022 +0100

    libtracker-miner: Handle FAN_DELETE[_SELF] being emitted separately on dirs
    
    If there is a monitor on a dir and its parent, fanotify used to be able to
    coalesce the event so FAN_DELETE and FAN_DELETE_SELF would be both set on
    an uniquely sent event.
    
    This seems no longer the case on more recent linux versions, where these
    generate 2 separate events, first FAN_DELETE_SELF for the folder being
    deleted, and then FAN_DELETE from the parent dir to notify of the parent
    folder structure change. This double DELETE event emission is inconsistent
    with TrackerMonitor behavior and causes test failures.
    
    Handle these 2 events, by caching both and being able to merge them, but
    flushing on the one that is expected last. Fixes tracker-file-notifier-test
    on recent linux versions (locally, 5.17.0).

 src/libtracker-miner/tracker-monitor-fanotify.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
---
diff --git a/src/libtracker-miner/tracker-monitor-fanotify.c b/src/libtracker-miner/tracker-monitor-fanotify.c
index 86f7878ef..7da262e89 100644
--- a/src/libtracker-miner/tracker-monitor-fanotify.c
+++ b/src/libtracker-miner/tracker-monitor-fanotify.c
@@ -222,6 +222,8 @@ cache_event (TrackerMonitorFanotify *monitor,
                        return;
                if (evtype == EVENT_UPDATE && prev_event->type == EVENT_UPDATE)
                        return;
+               if (evtype == EVENT_DELETE && prev_event->type == EVENT_DELETE)
+                       return;
 
                /* Otherwise flush the event */
                flush_event (monitor, file);
@@ -266,7 +268,9 @@ handle_monitor_events (TrackerMonitorFanotify *monitor,
        }
 
        if (mask & (FAN_DELETE | FAN_DELETE_SELF)) {
-               emit_event (monitor, EVENT_DELETE, file, NULL, is_directory);
+               cache_event (monitor, EVENT_DELETE, file, is_directory);
+               if (mask & FAN_DELETE)
+                       flush_event (monitor, file);
        }
 
        if (mask & FAN_CLOSE_WRITE) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]