fsnotify.c 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. * Copyright (C) 2008 Red Hat, Inc., Eric Paris <eparis@redhat.com>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2, or (at your option)
  7. * any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; see the file COPYING. If not, write to
  16. * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. #include <linux/dcache.h>
  19. #include <linux/fs.h>
  20. #include <linux/init.h>
  21. #include <linux/module.h>
  22. #include <linux/srcu.h>
  23. #include <linux/fsnotify_backend.h>
  24. #include "fsnotify.h"
  25. /*
  26. * Clear all of the marks on an inode when it is being evicted from core
  27. */
  28. void __fsnotify_inode_delete(struct inode *inode)
  29. {
  30. fsnotify_clear_marks_by_inode(inode);
  31. }
  32. EXPORT_SYMBOL_GPL(__fsnotify_inode_delete);
  33. /*
  34. * This is the main call to fsnotify. The VFS calls into hook specific functions
  35. * in linux/fsnotify.h. Those functions then in turn call here. Here will call
  36. * out to all of the registered fsnotify_group. Those groups can then use the
  37. * notification event in whatever means they feel necessary.
  38. */
  39. void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is)
  40. {
  41. struct fsnotify_group *group;
  42. struct fsnotify_event *event = NULL;
  43. int idx;
  44. if (list_empty(&fsnotify_groups))
  45. return;
  46. if (!(mask & fsnotify_mask))
  47. return;
  48. if (!(mask & to_tell->i_fsnotify_mask))
  49. return;
  50. /*
  51. * SRCU!! the groups list is very very much read only and the path is
  52. * very hot. The VAST majority of events are not going to need to do
  53. * anything other than walk the list so it's crazy to pre-allocate.
  54. */
  55. idx = srcu_read_lock(&fsnotify_grp_srcu);
  56. list_for_each_entry_rcu(group, &fsnotify_groups, group_list) {
  57. if (mask & group->mask) {
  58. if (!group->ops->should_send_event(group, to_tell, mask))
  59. continue;
  60. if (!event) {
  61. event = fsnotify_create_event(to_tell, mask, data, data_is);
  62. /* shit, we OOM'd and now we can't tell, maybe
  63. * someday someone else will want to do something
  64. * here */
  65. if (!event)
  66. break;
  67. }
  68. group->ops->handle_event(group, event);
  69. }
  70. }
  71. srcu_read_unlock(&fsnotify_grp_srcu, idx);
  72. /*
  73. * fsnotify_create_event() took a reference so the event can't be cleaned
  74. * up while we are still trying to add it to lists, drop that one.
  75. */
  76. if (event)
  77. fsnotify_put_event(event);
  78. }
  79. EXPORT_SYMBOL_GPL(fsnotify);
  80. static __init int fsnotify_init(void)
  81. {
  82. return init_srcu_struct(&fsnotify_grp_srcu);
  83. }
  84. subsys_initcall(fsnotify_init);