|
14 | 14 | #include <linux/poll.h> |
15 | 15 | #include <linux/pagemap.h> |
16 | 16 | #include <linux/sched.h> |
| 17 | +#include <linux/fsnotify.h> |
17 | 18 |
|
18 | 19 | #include "kernfs-internal.h" |
19 | 20 |
|
@@ -785,20 +786,48 @@ static unsigned int kernfs_fop_poll(struct file *filp, poll_table *wait) |
785 | 786 | */ |
786 | 787 | void kernfs_notify(struct kernfs_node *kn) |
787 | 788 | { |
| 789 | + struct kernfs_root *root = kernfs_root(kn); |
788 | 790 | struct kernfs_open_node *on; |
| 791 | + struct kernfs_super_info *info; |
789 | 792 | unsigned long flags; |
790 | 793 |
|
| 794 | + if (WARN_ON(kernfs_type(kn) != KERNFS_FILE)) |
| 795 | + return; |
| 796 | + |
| 797 | + /* kick poll */ |
791 | 798 | spin_lock_irqsave(&kernfs_open_node_lock, flags); |
792 | 799 |
|
793 | | - if (!WARN_ON(kernfs_type(kn) != KERNFS_FILE)) { |
794 | | - on = kn->attr.open; |
795 | | - if (on) { |
796 | | - atomic_inc(&on->event); |
797 | | - wake_up_interruptible(&on->poll); |
798 | | - } |
| 800 | + on = kn->attr.open; |
| 801 | + if (on) { |
| 802 | + atomic_inc(&on->event); |
| 803 | + wake_up_interruptible(&on->poll); |
799 | 804 | } |
800 | 805 |
|
801 | 806 | spin_unlock_irqrestore(&kernfs_open_node_lock, flags); |
| 807 | + |
| 808 | + /* kick fsnotify */ |
| 809 | + mutex_lock(&kernfs_mutex); |
| 810 | + |
| 811 | + list_for_each_entry(info, &root->supers, node) { |
| 812 | + struct inode *inode; |
| 813 | + struct dentry *dentry; |
| 814 | + |
| 815 | + inode = ilookup(info->sb, kn->ino); |
| 816 | + if (!inode) |
| 817 | + continue; |
| 818 | + |
| 819 | + dentry = d_find_any_alias(inode); |
| 820 | + if (dentry) { |
| 821 | + fsnotify_parent(NULL, dentry, FS_MODIFY); |
| 822 | + fsnotify(inode, FS_MODIFY, inode, FSNOTIFY_EVENT_INODE, |
| 823 | + NULL, 0); |
| 824 | + dput(dentry); |
| 825 | + } |
| 826 | + |
| 827 | + iput(inode); |
| 828 | + } |
| 829 | + |
| 830 | + mutex_unlock(&kernfs_mutex); |
802 | 831 | } |
803 | 832 | EXPORT_SYMBOL_GPL(kernfs_notify); |
804 | 833 |
|
|
0 commit comments