exportfs: clear DISCONNECTED on all parents sooner
Once we've found any connected parent, we know all our parents are connected--that's true even if there's a concurrent rename. May as well clear them all at once and be done with it. Reviewed-by: Cristoph Hellwig <hch@lst.de> Signed-off-by: J. Bruce Fields <bfields@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
78cee9a8e4
commit
0dbc018a49
|
@ -90,6 +90,24 @@ find_disconnected_root(struct dentry *dentry)
|
|||
return dentry;
|
||||
}
|
||||
|
||||
static void clear_disconnected(struct dentry *dentry)
|
||||
{
|
||||
dget(dentry);
|
||||
while (dentry->d_flags & DCACHE_DISCONNECTED) {
|
||||
struct dentry *parent = dget_parent(dentry);
|
||||
|
||||
WARN_ON_ONCE(IS_ROOT(dentry));
|
||||
|
||||
spin_lock(&dentry->d_lock);
|
||||
dentry->d_flags &= ~DCACHE_DISCONNECTED;
|
||||
spin_unlock(&dentry->d_lock);
|
||||
|
||||
dput(dentry);
|
||||
dentry = parent;
|
||||
}
|
||||
dput(dentry);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure target_dir is fully connected to the dentry tree.
|
||||
*
|
||||
|
@ -128,10 +146,9 @@ reconnect_path(struct vfsmount *mnt, struct dentry *target_dir, char *nbuf)
|
|||
|
||||
if (!IS_ROOT(pd)) {
|
||||
/* must have found a connected parent - great */
|
||||
spin_lock(&pd->d_lock);
|
||||
pd->d_flags &= ~DCACHE_DISCONNECTED;
|
||||
spin_unlock(&pd->d_lock);
|
||||
noprogress = 0;
|
||||
clear_disconnected(target_dir);
|
||||
dput(pd);
|
||||
break;
|
||||
} else {
|
||||
/*
|
||||
* We have hit the top of a disconnected path, try to
|
||||
|
|
Loading…
Reference in New Issue