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