aboutsummaryrefslogtreecommitdiffstats
path: root/fs/notify
diff options
context:
space:
mode:
Diffstat (limited to 'fs/notify')
-rw-r--r--fs/notify/fsnotify.c33
-rw-r--r--fs/notify/inode_mark.c2
2 files changed, 7 insertions, 28 deletions
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 36802420d69a..4498a208df94 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -88,8 +88,6 @@ void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
88{ 88{
89 struct dentry *parent; 89 struct dentry *parent;
90 struct inode *p_inode; 90 struct inode *p_inode;
91 bool send = false;
92 bool should_update_children = false;
93 91
94 if (!dentry) 92 if (!dentry)
95 dentry = path->dentry; 93 dentry = path->dentry;
@@ -97,29 +95,12 @@ void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
97 if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED)) 95 if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED))
98 return; 96 return;
99 97
100 spin_lock(&dentry->d_lock); 98 parent = dget_parent(dentry);
101 parent = dentry->d_parent;
102 p_inode = parent->d_inode; 99 p_inode = parent->d_inode;
103 100
104 if (fsnotify_inode_watches_children(p_inode)) { 101 if (unlikely(!fsnotify_inode_watches_children(p_inode)))
105 if (p_inode->i_fsnotify_mask & mask) { 102 __fsnotify_update_child_dentry_flags(p_inode);
106 dget(parent); 103 else if (p_inode->i_fsnotify_mask & mask) {
107 send = true;
108 }
109 } else {
110 /*
111 * The parent doesn't care about events on it's children but
112 * at least one child thought it did. We need to run all the
113 * children and update their d_flags to let them know p_inode
114 * doesn't care about them any more.
115 */
116 dget(parent);
117 should_update_children = true;
118 }
119
120 spin_unlock(&dentry->d_lock);
121
122 if (send) {
123 /* we are notifying a parent so come up with the new mask which 104 /* we are notifying a parent so come up with the new mask which
124 * specifies these are events which came from a child. */ 105 * specifies these are events which came from a child. */
125 mask |= FS_EVENT_ON_CHILD; 106 mask |= FS_EVENT_ON_CHILD;
@@ -130,13 +111,9 @@ void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
130 else 111 else
131 fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE, 112 fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE,
132 dentry->d_name.name, 0); 113 dentry->d_name.name, 0);
133 dput(parent);
134 } 114 }
135 115
136 if (unlikely(should_update_children)) { 116 dput(parent);
137 __fsnotify_update_child_dentry_flags(p_inode);
138 dput(parent);
139 }
140} 117}
141EXPORT_SYMBOL_GPL(__fsnotify_parent); 118EXPORT_SYMBOL_GPL(__fsnotify_parent);
142 119
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
index 33297c005060..21ed10660b80 100644
--- a/fs/notify/inode_mark.c
+++ b/fs/notify/inode_mark.c
@@ -240,6 +240,7 @@ void fsnotify_unmount_inodes(struct list_head *list)
240{ 240{
241 struct inode *inode, *next_i, *need_iput = NULL; 241 struct inode *inode, *next_i, *need_iput = NULL;
242 242
243 spin_lock(&inode_lock);
243 list_for_each_entry_safe(inode, next_i, list, i_sb_list) { 244 list_for_each_entry_safe(inode, next_i, list, i_sb_list) {
244 struct inode *need_iput_tmp; 245 struct inode *need_iput_tmp;
245 246
@@ -297,4 +298,5 @@ void fsnotify_unmount_inodes(struct list_head *list)
297 298
298 spin_lock(&inode_lock); 299 spin_lock(&inode_lock);
299 } 300 }
301 spin_unlock(&inode_lock);
300} 302}