fsnotify: use dget_parent
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:
Родитель
be9eee2e8b
Коммит
4d4eb36679
|
@ -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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче