36 #include <linux/kernel.h>
37 #include <linux/list.h>
38 #include <linux/module.h>
43 #include <linux/slab.h>
51 static struct kmem_cache *fsnotify_event_cachep;
52 static struct kmem_cache *fsnotify_event_holder_cachep;
59 static struct fsnotify_event *q_overflow_event;
75 BUG_ON(!mutex_is_locked(&group->notification_mutex));
76 return list_empty(&group->notification_list) ?
true :
false;
90 pr_debug(
"%s: event=%p\n", __func__, event);
92 if (event->data_type == FSNOTIFY_EVENT_PATH)
95 BUG_ON(!list_empty(&event->private_data_list));
97 kfree(event->file_name);
120 struct fsnotify_event_private_data *lpriv;
121 struct fsnotify_event_private_data *
priv =
NULL;
126 if (lpriv->group == group) {
141 struct fsnotify_event_private_data *
priv,
142 struct fsnotify_event *(*merge)(
struct list_head *,
143 struct fsnotify_event *))
145 struct fsnotify_event *return_event =
NULL;
146 struct fsnotify_event_holder *holder =
NULL;
149 pr_debug(
"%s: group=%p event=%p priv=%p\n", __func__, group, event, priv);
159 if (!list_empty(&event->holder.event_list)) {
168 if (group->q_len >= group->max_events) {
169 event = q_overflow_event;
176 return_event =
event;
182 if (!list_empty(list) && merge) {
183 struct fsnotify_event *
tmp;
185 tmp = merge(list, event);
191 if (holder != &event->holder)
197 spin_lock(&event->lock);
199 if (list_empty(&event->holder.event_list)) {
202 holder = &
event->holder;
206 spin_unlock(&event->lock);
218 holder->event =
event;
224 spin_unlock(&event->lock);
227 wake_up(&group->notification_waitq);
238 struct fsnotify_event *
event;
239 struct fsnotify_event_holder *holder;
241 BUG_ON(!mutex_is_locked(&group->notification_mutex));
243 pr_debug(
"%s: group=%p\n", __func__, group);
247 event = holder->event;
249 spin_lock(&event->lock);
250 holder->event =
NULL;
251 list_del_init(&holder->event_list);
252 spin_unlock(&event->lock);
255 if (holder != &event->holder)
268 struct fsnotify_event *
event;
269 struct fsnotify_event_holder *holder;
271 BUG_ON(!mutex_is_locked(&group->notification_mutex));
274 event = holder->event;
285 struct fsnotify_event *
event;
286 struct fsnotify_event_private_data *
priv;
292 if (group->ops->free_event_priv) {
293 spin_lock(&event->lock);
295 spin_unlock(&event->lock);
297 group->ops->free_event_priv(priv);
304 static void initialize_event(
struct fsnotify_event *event)
306 INIT_LIST_HEAD(&event->holder.event_list);
311 INIT_LIST_HEAD(&event->private_data_list);
320 struct fsnotify_event *new_event)
322 struct fsnotify_event *old_event = old_holder->event;
323 struct fsnotify_event_holder *new_holder = &new_event->holder;
325 enum event_spinlock_class {
330 pr_debug(
"%s: old_event=%p new_event=%p\n", __func__, old_event, new_event);
336 BUG_ON(!list_empty(&new_holder->event_list));
341 new_holder->event = new_event;
342 list_replace_init(&old_holder->event_list, &new_holder->event_list);
344 spin_unlock(&new_event->lock);
345 spin_unlock(&old_event->lock);
348 if (old_holder != &old_event->holder)
359 struct fsnotify_event *
event;
365 pr_debug(
"%s: old_event=%p new_event=%p\n", __func__, old_event, event);
367 memcpy(event, old_event,
sizeof(*event));
368 initialize_event(event);
370 if (event->name_len) {
372 if (!event->file_name) {
377 event->tgid = get_pid(old_event->tgid);
378 if (event->data_type == FSNOTIFY_EVENT_PATH)
400 struct fsnotify_event *
event;
402 event = kmem_cache_zalloc(fsnotify_event_cachep, gfp);
406 pr_debug(
"%s: event=%p to_tell=%p mask=%x data=%p data_type=%d\n",
407 __func__, event, to_tell, mask, data, data_type);
409 initialize_event(event);
412 event->file_name =
kstrdup(name, gfp);
413 if (!event->file_name) {
417 event->name_len =
strlen(event->file_name);
420 event->tgid = get_pid(task_tgid(
current));
421 event->sync_cookie =
cookie;
422 event->to_tell = to_tell;
426 case FSNOTIFY_EVENT_PATH: {
428 event->path.dentry = path->
dentry;
429 event->path.mnt = path->
mnt;
433 case FSNOTIFY_EVENT_INODE:
436 case FSNOTIFY_EVENT_NONE:
438 event->path.dentry =
NULL;
439 event->path.mnt =
NULL;
450 static __init int fsnotify_notification_init(
void)
456 FSNOTIFY_EVENT_NONE,
NULL, 0,
458 if (!q_overflow_event)
459 panic(
"unable to allocate fsnotify q_overflow_event\n");