diff options
Diffstat (limited to 'fs/notify')
-rw-r--r-- | fs/notify/fsnotify.c | 33 |
1 files changed, 5 insertions, 28 deletions
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 36802420d69..4498a208df9 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) { struct dentry *parent; struct inode *p_inode; - bool send = false; - bool should_update_children = false; if (!dentry) dentry = path->dentry; @@ -97,29 +95,12 @@ void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask) if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED)) return; - spin_lock(&dentry->d_lock); - parent = dentry->d_parent; + parent = dget_parent(dentry); p_inode = parent->d_inode; - if (fsnotify_inode_watches_children(p_inode)) { - if (p_inode->i_fsnotify_mask & mask) { - dget(parent); - send = true; - } - } else { - /* - * The parent doesn't care about events on it's children but - * at least one child thought it did. We need to run all the - * children and update their d_flags to let them know p_inode - * doesn't care about them any more. - */ - dget(parent); - should_update_children = true; - } - - spin_unlock(&dentry->d_lock); - - if (send) { + if (unlikely(!fsnotify_inode_watches_children(p_inode))) + __fsnotify_update_child_dentry_flags(p_inode); + else if (p_inode->i_fsnotify_mask & mask) { /* we are notifying a parent so come up with the new mask which * specifies these are events which came from a child. */ mask |= FS_EVENT_ON_CHILD; @@ -130,13 +111,9 @@ void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask) else fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0); - dput(parent); } - if (unlikely(should_update_children)) { - __fsnotify_update_child_dentry_flags(p_inode); - dput(parent); - } + dput(parent); } EXPORT_SYMBOL_GPL(__fsnotify_parent); |