@@ -2893,7 +2893,8 @@ restart:
if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
struct mount *parent = ACCESS_ONCE(mnt->mnt_parent);
/* Global root? */
- if (mnt != parent) {
+ if ((mnt != parent) &&
+ !(mnt->mnt.mnt_flags & MNT_UNREACHABLE_PARENT)) {
dentry = ACCESS_ONCE(mnt->mnt_mountpoint);
mnt = parent;
vfsmnt = &mnt->mnt;
@@ -938,7 +938,7 @@ static int follow_up_rcu(struct path *path)
struct dentry *mountpoint;
parent = mnt->mnt_parent;
- if (&parent->mnt == path->mnt)
+ if ((mnt->mnt.mnt_flags & MNT_UNREACHABLE_PARENT) || (parent == mnt))
return 0;
mountpoint = mnt->mnt_mountpoint;
path->dentry = mountpoint;
@@ -964,7 +964,7 @@ int follow_up(struct path *path)
read_seqlock_excl(&mount_lock);
parent = mnt->mnt_parent;
- if (parent == mnt) {
+ if ((mnt->mnt.mnt_flags & MNT_UNREACHABLE_PARENT) || (parent == mnt)) {
read_sequnlock_excl(&mount_lock);
return 0;
}
@@ -63,6 +63,7 @@ struct mnt_namespace;
#define MNT_MARKED 0x4000000
#define MNT_UMOUNT 0x8000000
#define MNT_VIOLATED 0x10000000
+#define MNT_UNREACHABLE_PARENT 0x20000000
struct vfsmount {
struct dentry *mnt_root; /* root of the mounted tree */
- Add a mount flag MNT_UNREACHABLE_PARENT to mark mounts that can not reach their parent mount's root from their mountpoint. - 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 | 3 ++- fs/namei.c | 4 ++-- include/linux/mount.h | 1 + 3 files changed, 5 insertions(+), 3 deletions(-)