1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/spinlock.h>
27#include <linux/idr.h>
28#include <linux/slab.h>
29#include <linux/fs.h>
30#include <linux/sched.h>
31#include <linux/init.h>
32#include <linux/list.h>
33#include <linux/writeback.h>
34#include <linux/inotify.h>
35
36static atomic_t inotify_cookie;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77struct inotify_handle {
78 struct idr idr;
79 struct mutex mutex;
80 struct list_head watches;
81 atomic_t count;
82 u32 last_wd;
83 const struct inotify_operations *in_ops;
84};
85
86static inline void get_inotify_handle(struct inotify_handle *ih)
87{
88 atomic_inc(&ih->count);
89}
90
91static inline void put_inotify_handle(struct inotify_handle *ih)
92{
93 if (atomic_dec_and_test(&ih->count)) {
94 idr_destroy(&ih->idr);
95 kfree(ih);
96 }
97}
98
99
100
101
102
103void get_inotify_watch(struct inotify_watch *watch)
104{
105 atomic_inc(&watch->count);
106}
107EXPORT_SYMBOL_GPL(get_inotify_watch);
108
109
110
111
112
113
114
115void put_inotify_watch(struct inotify_watch *watch)
116{
117 if (atomic_dec_and_test(&watch->count)) {
118 struct inotify_handle *ih = watch->ih;
119
120 iput(watch->inode);
121 ih->in_ops->destroy_watch(watch);
122 put_inotify_handle(ih);
123 }
124}
125EXPORT_SYMBOL_GPL(put_inotify_watch);
126
127
128
129
130
131
132static int inotify_handle_get_wd(struct inotify_handle *ih,
133 struct inotify_watch *watch)
134{
135 int ret;
136
137 do {
138 if (unlikely(!idr_pre_get(&ih->idr, GFP_KERNEL)))
139 return -ENOSPC;
140 ret = idr_get_new_above(&ih->idr, watch, ih->last_wd+1, &watch->wd);
141 } while (ret == -EAGAIN);
142
143 if (likely(!ret))
144 ih->last_wd = watch->wd;
145
146 return ret;
147}
148
149
150
151
152
153static inline int inotify_inode_watched(struct inode *inode)
154{
155 return !list_empty(&inode->inotify_watches);
156}
157
158
159
160
161
162static void set_dentry_child_flags(struct inode *inode, int watched)
163{
164 struct dentry *alias;
165
166 spin_lock(&dcache_lock);
167 list_for_each_entry(alias, &inode->i_dentry, d_alias) {
168 struct dentry *child;
169
170 list_for_each_entry(child, &alias->d_subdirs, d_u.d_child) {
171 if (!child->d_inode)
172 continue;
173
174 spin_lock(&child->d_lock);
175 if (watched)
176 child->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED;
177 else
178 child->d_flags &=~DCACHE_INOTIFY_PARENT_WATCHED;
179 spin_unlock(&child->d_lock);
180 }
181 }
182 spin_unlock(&dcache_lock);
183}
184
185
186
187
188
189
190
191static struct inotify_watch *inode_find_handle(struct inode *inode,
192 struct inotify_handle *ih)
193{
194 struct inotify_watch *watch;
195
196 list_for_each_entry(watch, &inode->inotify_watches, i_list) {
197 if (watch->ih == ih)
198 return watch;
199 }
200
201 return NULL;
202}
203
204
205
206
207
208
209static void remove_watch_no_event(struct inotify_watch *watch,
210 struct inotify_handle *ih)
211{
212 list_del(&watch->i_list);
213 list_del(&watch->h_list);
214
215 if (!inotify_inode_watched(watch->inode))
216 set_dentry_child_flags(watch->inode, 0);
217
218 idr_remove(&ih->idr, watch->wd);
219}
220
221
222
223
224
225
226
227
228
229
230void inotify_remove_watch_locked(struct inotify_handle *ih,
231 struct inotify_watch *watch)
232{
233 remove_watch_no_event(watch, ih);
234 ih->in_ops->handle_event(watch, watch->wd, IN_IGNORED, 0, NULL, NULL);
235}
236EXPORT_SYMBOL_GPL(inotify_remove_watch_locked);
237
238
239
240
241
242
243void inotify_d_instantiate(struct dentry *entry, struct inode *inode)
244{
245 struct dentry *parent;
246
247 if (!inode)
248 return;
249
250 spin_lock(&entry->d_lock);
251 parent = entry->d_parent;
252 if (parent->d_inode && inotify_inode_watched(parent->d_inode))
253 entry->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED;
254 spin_unlock(&entry->d_lock);
255}
256
257
258
259
260void inotify_d_move(struct dentry *entry)
261{
262 struct dentry *parent;
263
264 parent = entry->d_parent;
265 if (inotify_inode_watched(parent->d_inode))
266 entry->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED;
267 else
268 entry->d_flags &= ~DCACHE_INOTIFY_PARENT_WATCHED;
269}
270
271
272
273
274
275
276
277
278
279void inotify_inode_queue_event(struct inode *inode, u32 mask, u32 cookie,
280 const char *name, struct inode *n_inode)
281{
282 struct inotify_watch *watch, *next;
283
284 if (!inotify_inode_watched(inode))
285 return;
286
287 mutex_lock(&inode->inotify_mutex);
288 list_for_each_entry_safe(watch, next, &inode->inotify_watches, i_list) {
289 u32 watch_mask = watch->mask;
290 if (watch_mask & mask) {
291 struct inotify_handle *ih= watch->ih;
292 mutex_lock(&ih->mutex);
293 if (watch_mask & IN_ONESHOT)
294 remove_watch_no_event(watch, ih);
295 ih->in_ops->handle_event(watch, watch->wd, mask, cookie,
296 name, n_inode);
297 mutex_unlock(&ih->mutex);
298 }
299 }
300 mutex_unlock(&inode->inotify_mutex);
301}
302EXPORT_SYMBOL_GPL(inotify_inode_queue_event);
303
304
305
306
307
308
309
310
311void inotify_dentry_parent_queue_event(struct dentry *dentry, u32 mask,
312 u32 cookie, const char *name)
313{
314 struct dentry *parent;
315 struct inode *inode;
316
317 if (!(dentry->d_flags & DCACHE_INOTIFY_PARENT_WATCHED))
318 return;
319
320 spin_lock(&dentry->d_lock);
321 parent = dentry->d_parent;
322 inode = parent->d_inode;
323
324 if (inotify_inode_watched(inode)) {
325 dget(parent);
326 spin_unlock(&dentry->d_lock);
327 inotify_inode_queue_event(inode, mask, cookie, name,
328 dentry->d_inode);
329 dput(parent);
330 } else
331 spin_unlock(&dentry->d_lock);
332}
333EXPORT_SYMBOL_GPL(inotify_dentry_parent_queue_event);
334
335
336
337
338u32 inotify_get_cookie(void)
339{
340 return atomic_inc_return(&inotify_cookie);
341}
342EXPORT_SYMBOL_GPL(inotify_get_cookie);
343
344
345
346
347
348
349
350
351
352void inotify_unmount_inodes(struct list_head *list)
353{
354 struct inode *inode, *next_i, *need_iput = NULL;
355
356 list_for_each_entry_safe(inode, next_i, list, i_sb_list) {
357 struct inotify_watch *watch, *next_w;
358 struct inode *need_iput_tmp;
359 struct list_head *watches;
360
361
362
363
364
365
366
367 if (!atomic_read(&inode->i_count))
368 continue;
369
370
371
372
373
374
375 if (inode->i_state & (I_CLEAR | I_FREEING | I_WILL_FREE))
376 continue;
377
378 need_iput_tmp = need_iput;
379 need_iput = NULL;
380
381 if (inode != need_iput_tmp)
382 __iget(inode);
383 else
384 need_iput_tmp = NULL;
385
386 if ((&next_i->i_sb_list != list) &&
387 atomic_read(&next_i->i_count) &&
388 !(next_i->i_state & (I_CLEAR | I_FREEING |
389 I_WILL_FREE))) {
390 __iget(next_i);
391 need_iput = next_i;
392 }
393
394
395
396
397
398
399
400 spin_unlock(&inode_lock);
401
402 if (need_iput_tmp)
403 iput(need_iput_tmp);
404
405
406 mutex_lock(&inode->inotify_mutex);
407 watches = &inode->inotify_watches;
408 list_for_each_entry_safe(watch, next_w, watches, i_list) {
409 struct inotify_handle *ih= watch->ih;
410 mutex_lock(&ih->mutex);
411 ih->in_ops->handle_event(watch, watch->wd, IN_UNMOUNT, 0,
412 NULL, NULL);
413 inotify_remove_watch_locked(ih, watch);
414 mutex_unlock(&ih->mutex);
415 }
416 mutex_unlock(&inode->inotify_mutex);
417 iput(inode);
418
419 spin_lock(&inode_lock);
420 }
421}
422EXPORT_SYMBOL_GPL(inotify_unmount_inodes);
423
424
425
426
427
428void inotify_inode_is_dead(struct inode *inode)
429{
430 struct inotify_watch *watch, *next;
431
432 mutex_lock(&inode->inotify_mutex);
433 list_for_each_entry_safe(watch, next, &inode->inotify_watches, i_list) {
434 struct inotify_handle *ih = watch->ih;
435 mutex_lock(&ih->mutex);
436 inotify_remove_watch_locked(ih, watch);
437 mutex_unlock(&ih->mutex);
438 }
439 mutex_unlock(&inode->inotify_mutex);
440}
441EXPORT_SYMBOL_GPL(inotify_inode_is_dead);
442
443
444
445
446
447
448
449struct inotify_handle *inotify_init(const struct inotify_operations *ops)
450{
451 struct inotify_handle *ih;
452
453 ih = kmalloc(sizeof(struct inotify_handle), GFP_KERNEL);
454 if (unlikely(!ih))
455 return ERR_PTR(-ENOMEM);
456
457 idr_init(&ih->idr);
458 INIT_LIST_HEAD(&ih->watches);
459 mutex_init(&ih->mutex);
460 ih->last_wd = 0;
461 ih->in_ops = ops;
462 atomic_set(&ih->count, 0);
463 get_inotify_handle(ih);
464
465 return ih;
466}
467EXPORT_SYMBOL_GPL(inotify_init);
468
469
470
471
472
473void inotify_init_watch(struct inotify_watch *watch)
474{
475 INIT_LIST_HEAD(&watch->h_list);
476 INIT_LIST_HEAD(&watch->i_list);
477 atomic_set(&watch->count, 0);
478 get_inotify_watch(watch);
479}
480EXPORT_SYMBOL_GPL(inotify_init_watch);
481
482
483
484
485
486void inotify_destroy(struct inotify_handle *ih)
487{
488
489
490
491
492
493
494 while (1) {
495 struct inotify_watch *watch;
496 struct list_head *watches;
497 struct inode *inode;
498
499 mutex_lock(&ih->mutex);
500 watches = &ih->watches;
501 if (list_empty(watches)) {
502 mutex_unlock(&ih->mutex);
503 break;
504 }
505 watch = list_first_entry(watches, struct inotify_watch, h_list);
506 get_inotify_watch(watch);
507 mutex_unlock(&ih->mutex);
508
509 inode = watch->inode;
510 mutex_lock(&inode->inotify_mutex);
511 mutex_lock(&ih->mutex);
512
513
514 if (likely(idr_find(&ih->idr, watch->wd))) {
515 remove_watch_no_event(watch, ih);
516 put_inotify_watch(watch);
517 }
518
519 mutex_unlock(&ih->mutex);
520 mutex_unlock(&inode->inotify_mutex);
521 put_inotify_watch(watch);
522 }
523
524
525 put_inotify_handle(ih);
526}
527EXPORT_SYMBOL_GPL(inotify_destroy);
528
529
530
531
532
533
534
535
536
537s32 inotify_find_watch(struct inotify_handle *ih, struct inode *inode,
538 struct inotify_watch **watchp)
539{
540 struct inotify_watch *old;
541 int ret = -ENOENT;
542
543 mutex_lock(&inode->inotify_mutex);
544 mutex_lock(&ih->mutex);
545
546 old = inode_find_handle(inode, ih);
547 if (unlikely(old)) {
548 get_inotify_watch(old);
549 *watchp = old;
550 ret = old->wd;
551 }
552
553 mutex_unlock(&ih->mutex);
554 mutex_unlock(&inode->inotify_mutex);
555
556 return ret;
557}
558EXPORT_SYMBOL_GPL(inotify_find_watch);
559
560
561
562
563
564
565
566
567
568s32 inotify_find_update_watch(struct inotify_handle *ih, struct inode *inode,
569 u32 mask)
570{
571 struct inotify_watch *old;
572 int mask_add = 0;
573 int ret;
574
575 if (mask & IN_MASK_ADD)
576 mask_add = 1;
577
578
579 mask &= IN_ALL_EVENTS | IN_ONESHOT;
580 if (unlikely(!mask))
581 return -EINVAL;
582
583 mutex_lock(&inode->inotify_mutex);
584 mutex_lock(&ih->mutex);
585
586
587
588
589
590 old = inode_find_handle(inode, ih);
591 if (unlikely(!old)) {
592 ret = -ENOENT;
593 goto out;
594 }
595
596 if (mask_add)
597 old->mask |= mask;
598 else
599 old->mask = mask;
600 ret = old->wd;
601out:
602 mutex_unlock(&ih->mutex);
603 mutex_unlock(&inode->inotify_mutex);
604 return ret;
605}
606EXPORT_SYMBOL_GPL(inotify_find_update_watch);
607
608
609
610
611
612
613
614
615
616
617
618
619s32 inotify_add_watch(struct inotify_handle *ih, struct inotify_watch *watch,
620 struct inode *inode, u32 mask)
621{
622 int ret = 0;
623 int newly_watched;
624
625
626 mask &= IN_ALL_EVENTS | IN_ONESHOT;
627 if (unlikely(!mask))
628 return -EINVAL;
629 watch->mask = mask;
630
631 mutex_lock(&inode->inotify_mutex);
632 mutex_lock(&ih->mutex);
633
634
635 ret = inotify_handle_get_wd(ih, watch);
636 if (unlikely(ret))
637 goto out;
638 ret = watch->wd;
639
640
641 get_inotify_handle(ih);
642 watch->ih = ih;
643
644
645
646
647
648 watch->inode = igrab(inode);
649
650
651 newly_watched = !inotify_inode_watched(inode);
652 list_add(&watch->h_list, &ih->watches);
653 list_add(&watch->i_list, &inode->inotify_watches);
654
655
656
657
658
659 if (newly_watched)
660 set_dentry_child_flags(inode, 1);
661
662out:
663 mutex_unlock(&ih->mutex);
664 mutex_unlock(&inode->inotify_mutex);
665 return ret;
666}
667EXPORT_SYMBOL_GPL(inotify_add_watch);
668
669
670
671
672
673
674
675
676
677s32 inotify_clone_watch(struct inotify_watch *old, struct inotify_watch *new)
678{
679 struct inotify_handle *ih = old->ih;
680 int ret = 0;
681
682 new->mask = old->mask;
683 new->ih = ih;
684
685 mutex_lock(&ih->mutex);
686
687
688 ret = inotify_handle_get_wd(ih, new);
689 if (unlikely(ret))
690 goto out;
691 ret = new->wd;
692
693 get_inotify_handle(ih);
694
695 new->inode = igrab(old->inode);
696
697 list_add(&new->h_list, &ih->watches);
698 list_add(&new->i_list, &old->inode->inotify_watches);
699out:
700 mutex_unlock(&ih->mutex);
701 return ret;
702}
703
704void inotify_evict_watch(struct inotify_watch *watch)
705{
706 get_inotify_watch(watch);
707 mutex_lock(&watch->ih->mutex);
708 inotify_remove_watch_locked(watch->ih, watch);
709 mutex_unlock(&watch->ih->mutex);
710}
711
712
713
714
715
716
717
718
719int inotify_rm_wd(struct inotify_handle *ih, u32 wd)
720{
721 struct inotify_watch *watch;
722 struct inode *inode;
723
724 mutex_lock(&ih->mutex);
725 watch = idr_find(&ih->idr, wd);
726 if (unlikely(!watch)) {
727 mutex_unlock(&ih->mutex);
728 return -EINVAL;
729 }
730 get_inotify_watch(watch);
731 inode = watch->inode;
732 mutex_unlock(&ih->mutex);
733
734 mutex_lock(&inode->inotify_mutex);
735 mutex_lock(&ih->mutex);
736
737
738 if (likely(idr_find(&ih->idr, wd) == watch))
739 inotify_remove_watch_locked(ih, watch);
740
741 mutex_unlock(&ih->mutex);
742 mutex_unlock(&inode->inotify_mutex);
743 put_inotify_watch(watch);
744
745 return 0;
746}
747EXPORT_SYMBOL_GPL(inotify_rm_wd);
748
749
750
751
752
753
754
755
756int inotify_rm_watch(struct inotify_handle *ih,
757 struct inotify_watch *watch)
758{
759 return inotify_rm_wd(ih, watch->wd);
760}
761EXPORT_SYMBOL_GPL(inotify_rm_watch);
762
763
764
765
766static int __init inotify_setup(void)
767{
768 atomic_set(&inotify_cookie, 0);
769
770 return 0;
771}
772
773module_init(inotify_setup);
774