Commit 9dced01a authored by Eric Paris's avatar Eric Paris

fanotify: do not clone on merge unless needed

Currently if 2 events are going to be merged on the notication queue with
different masks the second event will be cloned and will replace the first
event.  However if this notification queue is the only place referencing
the event in question there is no reason not to just update the event in
place.  We can tell this if the event->refcnt == 1.  Since we hold a
reference for each queue this event is on we know that when refcnt == 1
this is the only queue.  The other concern is that it might be about to be
added to a new queue, but this can't be the case since fsnotify holds a
reference on the event until it is finished adding it to queues.
Signed-off-by: default avatarEric Paris <eparis@redhat.com>
parent a12a7dd3
...@@ -46,6 +46,16 @@ static int fanotify_merge(struct list_head *list, struct fsnotify_event *event) ...@@ -46,6 +46,16 @@ static int fanotify_merge(struct list_head *list, struct fsnotify_event *event)
if (test_event->mask == event->mask) if (test_event->mask == event->mask)
goto out; goto out;
/*
* if the refcnt == 1 this is the only queue
* for this event and so we can update the mask
* in place.
*/
if (atomic_read(&test_event->refcnt) == 1) {
test_event->mask |= event->mask;
goto out;
}
/* can't allocate memory, merge was no possible */ /* can't allocate memory, merge was no possible */
new_event = fsnotify_clone_event(test_event); new_event = fsnotify_clone_event(test_event);
if (unlikely(!new_event)) { if (unlikely(!new_event)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment