mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
vfs: add path_has_submounts()
d_mountpoint() can only be used reliably to establish if a dentry is not mounted in any namespace. It isn't aware of the possibility there may be multiple mounts using the given dentry, possibly in a different namespace. Add function, path_has_submounts(), that checks is a struct path contains mounts (or is a mountpoint itself) to handle this case. Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ian Kent <[email protected]> Cc: Al Viro <[email protected]> Cc: Eric W. Biederman <[email protected]> Cc: Omar Sandoval <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Al Viro <[email protected]>
This commit is contained in:
parent
c6609c0a1c
commit
01619491a5
2 changed files with 40 additions and 0 deletions
39
fs/dcache.c
39
fs/dcache.c
|
|
@ -1306,6 +1306,45 @@ int have_submounts(struct dentry *parent)
|
|||
}
|
||||
EXPORT_SYMBOL(have_submounts);
|
||||
|
||||
struct check_mount {
|
||||
struct vfsmount *mnt;
|
||||
unsigned int mounted;
|
||||
};
|
||||
|
||||
static enum d_walk_ret path_check_mount(void *data, struct dentry *dentry)
|
||||
{
|
||||
struct check_mount *info = data;
|
||||
struct path path = { .mnt = info->mnt, .dentry = dentry };
|
||||
|
||||
if (likely(!d_mountpoint(dentry)))
|
||||
return D_WALK_CONTINUE;
|
||||
if (__path_is_mountpoint(&path)) {
|
||||
info->mounted = 1;
|
||||
return D_WALK_QUIT;
|
||||
}
|
||||
return D_WALK_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* path_has_submounts - check for mounts over a dentry in the
|
||||
* current namespace.
|
||||
* @parent: path to check.
|
||||
*
|
||||
* Return true if the parent or its subdirectories contain
|
||||
* a mount point in the current namespace.
|
||||
*/
|
||||
int path_has_submounts(const struct path *parent)
|
||||
{
|
||||
struct check_mount data = { .mnt = parent->mnt, .mounted = 0 };
|
||||
|
||||
read_seqlock_excl(&mount_lock);
|
||||
d_walk(parent->dentry, &data, path_check_mount, NULL);
|
||||
read_sequnlock_excl(&mount_lock);
|
||||
|
||||
return data.mounted;
|
||||
}
|
||||
EXPORT_SYMBOL(path_has_submounts);
|
||||
|
||||
/*
|
||||
* Called by mount code to set a mountpoint and check if the mountpoint is
|
||||
* reachable (e.g. NFS can unhash a directory dentry and then the complete
|
||||
|
|
|
|||
Loading…
Reference in a new issue