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>
This commit is contained in:
Christoph Hellwig 2010-10-10 05:36:30 -04:00 коммит произвёл Al Viro
Родитель be9eee2e8b
Коммит 4d4eb36679
1 изменённых файлов: 5 добавлений и 28 удалений

Просмотреть файл

@ -88,8 +88,6 @@ void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
{ {
struct dentry *parent; struct dentry *parent;
struct inode *p_inode; struct inode *p_inode;
bool send = false;
bool should_update_children = false;
if (!dentry) if (!dentry)
dentry = path->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)) if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED))
return; return;
spin_lock(&dentry->d_lock); parent = dget_parent(dentry);
parent = dentry->d_parent;
p_inode = parent->d_inode; p_inode = parent->d_inode;
if (fsnotify_inode_watches_children(p_inode)) { if (unlikely(!fsnotify_inode_watches_children(p_inode)))
if (p_inode->i_fsnotify_mask & mask) { __fsnotify_update_child_dentry_flags(p_inode);
dget(parent); else if (p_inode->i_fsnotify_mask & mask) {
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) {
/* we are notifying a parent so come up with the new mask which /* we are notifying a parent so come up with the new mask which
* specifies these are events which came from a child. */ * specifies these are events which came from a child. */
mask |= FS_EVENT_ON_CHILD; mask |= FS_EVENT_ON_CHILD;
@ -130,14 +111,10 @@ void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
else else
fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE, fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE,
dentry->d_name.name, 0); 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); EXPORT_SYMBOL_GPL(__fsnotify_parent);
static int send_to_group(struct inode *to_tell, struct vfsmount *mnt, static int send_to_group(struct inode *to_tell, struct vfsmount *mnt,