Skip to content

Commit

Permalink
fsnotify: use dget_parent
Browse files Browse the repository at this point in the history
Use dget_parent instead of opencoding it.  This simplifies the code, but
more importanly prepares for the more complicated locking for a parent
dget in the dcache scale patch series.

It means we do grab a reference to the parent now if need to be watched,
but not with the specified mask.  If this turns out to be a problem
we'll have to revisit it, but for now let's keep as much as possible
dcache internals inside dcache.[ch].

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
  • Loading branch information
Christoph Hellwig authored and Al Viro committed Oct 26, 2010
1 parent be9eee2 commit 4d4eb36
Showing 1 changed file with 5 additions and 28 deletions.
33 changes: 5 additions & 28 deletions fs/notify/fsnotify.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,38 +88,19 @@ 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;

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;
Expand All @@ -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);

Expand Down

0 comments on commit 4d4eb36

Please sign in to comment.