|
@@ -667,6 +667,41 @@ struct vfsmount *lookup_mnt(struct path *path)
|
|
|
return m;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * __is_local_mountpoint - Test to see if dentry is a mountpoint in the
|
|
|
+ * current mount namespace.
|
|
|
+ *
|
|
|
+ * The common case is dentries are not mountpoints at all and that
|
|
|
+ * test is handled inline. For the slow case when we are actually
|
|
|
+ * dealing with a mountpoint of some kind, walk through all of the
|
|
|
+ * mounts in the current mount namespace and test to see if the dentry
|
|
|
+ * is a mountpoint.
|
|
|
+ *
|
|
|
+ * The mount_hashtable is not usable in the context because we
|
|
|
+ * need to identify all mounts that may be in the current mount
|
|
|
+ * namespace not just a mount that happens to have some specified
|
|
|
+ * parent mount.
|
|
|
+ */
|
|
|
+bool __is_local_mountpoint(struct dentry *dentry)
|
|
|
+{
|
|
|
+ struct mnt_namespace *ns = current->nsproxy->mnt_ns;
|
|
|
+ struct mount *mnt;
|
|
|
+ bool is_covered = false;
|
|
|
+
|
|
|
+ if (!d_mountpoint(dentry))
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ down_read(&namespace_sem);
|
|
|
+ list_for_each_entry(mnt, &ns->list, mnt_list) {
|
|
|
+ is_covered = (mnt->mnt_mountpoint == dentry);
|
|
|
+ if (is_covered)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ up_read(&namespace_sem);
|
|
|
+out:
|
|
|
+ return is_covered;
|
|
|
+}
|
|
|
+
|
|
|
static struct mountpoint *new_mountpoint(struct dentry *dentry)
|
|
|
{
|
|
|
struct hlist_head *chain = mp_hash(dentry);
|