@@ -2894,10 +2894,16 @@ restart:
struct mount *parent = ACCESS_ONCE(mnt->mnt_parent);
/* Global root? */
if (mnt != parent) {
- dentry = ACCESS_ONCE(mnt->mnt_mountpoint);
- mnt = parent;
- vfsmnt = &mnt->mnt;
- continue;
+ struct path new = {
+ .dentry = ACCESS_ONCE(mnt->mnt_mountpoint),
+ .mnt = &parent->mnt,
+ };
+ if (path_connected(&new)) {
+ mnt = parent;
+ dentry = new.dentry;
+ vfsmnt = new.mnt;
+ continue;
+ }
}
/*
* Filesystems needing to implement special "root names"
@@ -935,14 +935,16 @@ static int follow_up_rcu(struct path *path)
{
struct mount *mnt = real_mount(path->mnt);
struct mount *parent;
- struct dentry *mountpoint;
+ struct path new;
parent = mnt->mnt_parent;
- if (&parent->mnt == path->mnt)
+ if (parent == mnt)
return 0;
- mountpoint = mnt->mnt_mountpoint;
- path->dentry = mountpoint;
- path->mnt = &parent->mnt;
+ new.dentry = mnt->mnt_mountpoint;
+ new.mnt = &parent->mnt;
+ if (!path_connected(&new))
+ return 0;
+ *path = new;
return 1;
}
@@ -960,7 +962,7 @@ int follow_up(struct path *path)
{
struct mount *mnt = real_mount(path->mnt);
struct mount *parent;
- struct dentry *mountpoint;
+ struct path new;
read_seqlock_excl(&mount_lock);
parent = mnt->mnt_parent;
@@ -968,13 +970,18 @@ int follow_up(struct path *path)
read_sequnlock_excl(&mount_lock);
return 0;
}
- mntget(&parent->mnt);
- mountpoint = dget(mnt->mnt_mountpoint);
+ new.dentry = mnt->mnt_mountpoint;
+ new.mnt = &parent->mnt;
+ if (!path_connected(&new)) {
+ read_sequnlock_excl(&mount_lock);
+ return 0;
+ }
+ mntget(new.mnt);
+ dget(new.dentry);
read_sequnlock_excl(&mount_lock);
dput(path->dentry);
- path->dentry = mountpoint;
mntput(path->mnt);
- path->mnt = &parent->mnt;
+ *path = new;
return 1;
}
EXPORT_SYMBOL(follow_up);
- In follup_up and follow_up_rcu don't follow up if the current mount's mountpoint can not reach the parent mount's root. - In prepend_path and it's callers in the d_path family don't follow to the parent mount if the current mount's mountpoint can not reach the parent mount's root. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> --- fs/dcache.c | 14 ++++++++++---- fs/namei.c | 27 +++++++++++++++++---------- 2 files changed, 27 insertions(+), 14 deletions(-)