diff options
| -rw-r--r-- | fs/kernfs/file.c | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 8034706a7af8..98bacd9ea7fd 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/poll.h> | 14 | #include <linux/poll.h> |
| 15 | #include <linux/pagemap.h> | 15 | #include <linux/pagemap.h> |
| 16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
| 17 | #include <linux/fsnotify.h> | ||
| 17 | 18 | ||
| 18 | #include "kernfs-internal.h" | 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 | void kernfs_notify(struct kernfs_node *kn) | 787 | void kernfs_notify(struct kernfs_node *kn) |
| 787 | { | 788 | { |
| 789 | struct kernfs_root *root = kernfs_root(kn); | ||
| 788 | struct kernfs_open_node *on; | 790 | struct kernfs_open_node *on; |
| 791 | struct kernfs_super_info *info; | ||
| 789 | unsigned long flags; | 792 | unsigned long flags; |
| 790 | 793 | ||
| 794 | if (WARN_ON(kernfs_type(kn) != KERNFS_FILE)) | ||
| 795 | return; | ||
| 796 | |||
| 797 | /* kick poll */ | ||
| 791 | spin_lock_irqsave(&kernfs_open_node_lock, flags); | 798 | spin_lock_irqsave(&kernfs_open_node_lock, flags); |
| 792 | 799 | ||
| 793 | if (!WARN_ON(kernfs_type(kn) != KERNFS_FILE)) { | 800 | on = kn->attr.open; |
| 794 | on = kn->attr.open; | 801 | if (on) { |
| 795 | if (on) { | 802 | atomic_inc(&on->event); |
| 796 | atomic_inc(&on->event); | 803 | wake_up_interruptible(&on->poll); |
| 797 | wake_up_interruptible(&on->poll); | ||
| 798 | } | ||
| 799 | } | 804 | } |
| 800 | 805 | ||
| 801 | spin_unlock_irqrestore(&kernfs_open_node_lock, flags); | 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 | EXPORT_SYMBOL_GPL(kernfs_notify); | 832 | EXPORT_SYMBOL_GPL(kernfs_notify); |
| 804 | 833 | ||
