^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2008 Red Hat, Inc., Eric Paris <eparis@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/srcu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/rculist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/memcontrol.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/fsnotify_backend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "fsnotify.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Final freeing of a group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static void fsnotify_final_destroy_group(struct fsnotify_group *group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) if (group->ops->free_group_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) group->ops->free_group_priv(group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) mem_cgroup_put(group->memcg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) mutex_destroy(&group->mark_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) kfree(group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * Stop queueing new events for this group. Once this function returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * fsnotify_add_event() will not add any new events to the group's queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) void fsnotify_group_stop_queueing(struct fsnotify_group *group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) spin_lock(&group->notification_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) group->shutdown = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) spin_unlock(&group->notification_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * Trying to get rid of a group. Remove all marks, flush all events and release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * the group reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * Note that another thread calling fsnotify_clear_marks_by_group() may still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * hold a ref to the group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) void fsnotify_destroy_group(struct fsnotify_group *group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * Stop queueing new events. The code below is careful enough to not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * require this but fanotify needs to stop queuing events even before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * fsnotify_destroy_group() is called and this makes the other callers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * of fsnotify_destroy_group() to see the same behavior.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) fsnotify_group_stop_queueing(group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* Clear all marks for this group and queue them for destruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_ALL_TYPES_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * Some marks can still be pinned when waiting for response from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * userspace. Wait for those now. fsnotify_prepare_user_wait() will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * not succeed now so this wait is race-free.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) wait_event(group->notification_waitq, !atomic_read(&group->user_waits));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * Wait until all marks get really destroyed. We could actually destroy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * them ourselves instead of waiting for worker to do it, however that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * would be racy as worker can already be processing some marks before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * we even entered fsnotify_destroy_group().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) fsnotify_wait_marks_destroyed();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * Since we have waited for fsnotify_mark_srcu in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * fsnotify_mark_destroy_list() there can be no outstanding event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * notification against this group. So clearing the notification queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * of all events is reliable now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) fsnotify_flush_notify(group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * Destroy overflow event (we cannot use fsnotify_destroy_event() as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * that deliberately ignores overflow events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (group->overflow_event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) group->ops->free_event(group->overflow_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) fsnotify_put_group(group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * Get reference to a group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) void fsnotify_get_group(struct fsnotify_group *group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) refcount_inc(&group->refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * Drop a reference to a group. Free it if it's through.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) void fsnotify_put_group(struct fsnotify_group *group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (refcount_dec_and_test(&group->refcnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) fsnotify_final_destroy_group(group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) EXPORT_SYMBOL_GPL(fsnotify_put_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * Create a new fsnotify_group and hold a reference for the group returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct fsnotify_group *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) group = kzalloc(sizeof(struct fsnotify_group), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (!group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* set to 0 when there a no external references to this group */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) refcount_set(&group->refcnt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) atomic_set(&group->num_marks, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) atomic_set(&group->user_waits, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) spin_lock_init(&group->notification_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) INIT_LIST_HEAD(&group->notification_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) init_waitqueue_head(&group->notification_waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) group->max_events = UINT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) mutex_init(&group->mark_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) INIT_LIST_HEAD(&group->marks_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) group->ops = ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) EXPORT_SYMBOL_GPL(fsnotify_alloc_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) int fsnotify_fasync(int fd, struct file *file, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct fsnotify_group *group = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return fasync_helper(fd, file, on, &group->fsn_fa) >= 0 ? 0 : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }