diff options
Diffstat (limited to 'fs/namespace.c')
| -rw-r--r-- | fs/namespace.c | 39 | 
1 files changed, 34 insertions, 5 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index e6c234b1a645..f7e28f8ea04d 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -678,7 +678,7 @@ out:   *   * lookup_mnt takes a reference to the found vfsmount.   */ -struct vfsmount *lookup_mnt(struct path *path) +struct vfsmount *lookup_mnt(const struct path *path)  {  	struct mount *child_mnt;  	struct vfsmount *m; @@ -1159,7 +1159,36 @@ struct vfsmount *mntget(struct vfsmount *mnt)  }  EXPORT_SYMBOL(mntget); -struct vfsmount *mnt_clone_internal(struct path *path) +/* path_is_mountpoint() - Check if path is a mount in the current + *                          namespace. + * + *  d_mountpoint() can only be used reliably to establish if a dentry is + *  not mounted in any namespace and that common case is handled inline. + *  d_mountpoint() isn't aware of the possibility there may be multiple + *  mounts using a given dentry in a different namespace. This function + *  checks if the passed in path is a mountpoint rather than the dentry + *  alone. + */ +bool path_is_mountpoint(const struct path *path) +{ +	unsigned seq; +	bool res; + +	if (!d_mountpoint(path->dentry)) +		return false; + +	rcu_read_lock(); +	do { +		seq = read_seqbegin(&mount_lock); +		res = __path_is_mountpoint(path); +	} while (read_seqretry(&mount_lock, seq)); +	rcu_read_unlock(); + +	return res; +} +EXPORT_SYMBOL(path_is_mountpoint); + +struct vfsmount *mnt_clone_internal(const struct path *path)  {  	struct mount *p;  	p = clone_mnt(real_mount(path->mnt), path->dentry, CL_PRIVATE); @@ -1758,7 +1787,7 @@ out:  /* Caller should check returned pointer for errors */ -struct vfsmount *collect_mounts(struct path *path) +struct vfsmount *collect_mounts(const struct path *path)  {  	struct mount *tree;  	namespace_lock(); @@ -1791,7 +1820,7 @@ void drop_collected_mounts(struct vfsmount *mnt)   *   * Release with mntput().   */ -struct vfsmount *clone_private_mount(struct path *path) +struct vfsmount *clone_private_mount(const struct path *path)  {  	struct mount *old_mnt = real_mount(path->mnt);  	struct mount *new_mnt; @@ -2997,7 +3026,7 @@ bool is_path_reachable(struct mount *mnt, struct dentry *dentry,  	return &mnt->mnt == root->mnt && is_subdir(dentry, root->dentry);  } -bool path_is_under(struct path *path1, struct path *path2) +bool path_is_under(const struct path *path1, const struct path *path2)  {  	bool res;  	read_seqlock_excl(&mount_lock);  |