linux/fs/pnode.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/fs/pnode.c
 *
 * (C) Copyright IBM Corporation 2005.
 *	Author : Ram Pai ([email protected])
 */
#include <linux/mnt_namespace.h>
#include <linux/mount.h>
#include <linux/fs.h>
#include <linux/nsproxy.h>
#include <uapi/linux/mount.h>
#include "internal.h"
#include "pnode.h"

/* return the next shared peer mount of @p */
static inline struct mount *next_peer(struct mount *p)
{}

static inline struct mount *first_slave(struct mount *p)
{}

static inline struct mount *last_slave(struct mount *p)
{}

static inline struct mount *next_slave(struct mount *p)
{}

static struct mount *get_peer_under_root(struct mount *mnt,
					 struct mnt_namespace *ns,
					 const struct path *root)
{}

/*
 * Get ID of closest dominating peer group having a representative
 * under the given root.
 *
 * Caller must hold namespace_sem
 */
int get_dominating_id(struct mount *mnt, const struct path *root)
{}

static int do_make_slave(struct mount *mnt)
{}

/*
 * vfsmount lock must be held for write
 */
void change_mnt_propagation(struct mount *mnt, int type)
{}

/*
 * get the next mount in the propagation tree.
 * @m: the mount seen last
 * @origin: the original mount from where the tree walk initiated
 *
 * Note that peer groups form contiguous segments of slave lists.
 * We rely on that in get_source() to be able to find out if
 * vfsmount found while iterating with propagation_next() is
 * a peer of one we'd found earlier.
 */
static struct mount *propagation_next(struct mount *m,
					 struct mount *origin)
{}

static struct mount *skip_propagation_subtree(struct mount *m,
						struct mount *origin)
{}

static struct mount *next_group(struct mount *m, struct mount *origin)
{}

/* all accesses are serialized by namespace_sem */
static struct mount *last_dest, *first_source, *last_source, *dest_master;
static struct hlist_head *list;

static inline bool peers(const struct mount *m1, const struct mount *m2)
{}

static int propagate_one(struct mount *m, struct mountpoint *dest_mp)
{}

/*
 * mount 'source_mnt' under the destination 'dest_mnt' at
 * dentry 'dest_dentry'. And propagate that mount to
 * all the peer and slave mounts of 'dest_mnt'.
 * Link all the new mounts into a propagation tree headed at
 * source_mnt. Also link all the new mounts using ->mnt_list
 * headed at source_mnt's ->mnt_list
 *
 * @dest_mnt: destination mount.
 * @dest_dentry: destination dentry.
 * @source_mnt: source mount.
 * @tree_list : list of heads of trees to be attached.
 */
int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp,
		    struct mount *source_mnt, struct hlist_head *tree_list)
{}

static struct mount *find_topper(struct mount *mnt)
{}

/*
 * return true if the refcount is greater than count
 */
static inline int do_refcount_check(struct mount *mnt, int count)
{}

/**
 * propagation_would_overmount - check whether propagation from @from
 *                               would overmount @to
 * @from: shared mount
 * @to:   mount to check
 * @mp:   future mountpoint of @to on @from
 *
 * If @from propagates mounts to @to, @from and @to must either be peers
 * or one of the masters in the hierarchy of masters of @to must be a
 * peer of @from.
 *
 * If the root of the @to mount is equal to the future mountpoint @mp of
 * the @to mount on @from then @to will be overmounted by whatever is
 * propagated to it.
 *
 * Context: This function expects namespace_lock() to be held and that
 *          @mp is stable.
 * Return: If @from overmounts @to, true is returned, false if not.
 */
bool propagation_would_overmount(const struct mount *from,
				 const struct mount *to,
				 const struct mountpoint *mp)
{}

/*
 * check if the mount 'mnt' can be unmounted successfully.
 * @mnt: the mount to be checked for unmount
 * NOTE: unmounting 'mnt' would naturally propagate to all
 * other mounts its parent propagates to.
 * Check if any of these mounts that **do not have submounts**
 * have more references than 'refcnt'. If so return busy.
 *
 * vfsmount lock must be held for write
 */
int propagate_mount_busy(struct mount *mnt, int refcnt)
{}

/*
 * Clear MNT_LOCKED when it can be shown to be safe.
 *
 * mount_lock lock must be held for write
 */
void propagate_mount_unlock(struct mount *mnt)
{}

static void umount_one(struct mount *mnt, struct list_head *to_umount)
{}

/*
 * NOTE: unmounting 'mnt' naturally propagates to all other mounts its
 * parent propagates to.
 */
static bool __propagate_umount(struct mount *mnt,
			       struct list_head *to_umount,
			       struct list_head *to_restore)
{}

static void umount_list(struct list_head *to_umount,
			struct list_head *to_restore)
{}

static void restore_mounts(struct list_head *to_restore)
{}

static void cleanup_umount_visitations(struct list_head *visited)
{}

/*
 * collect all mounts that receive propagation from the mount in @list,
 * and return these additional mounts in the same list.
 * @list: the list of mounts to be unmounted.
 *
 * vfsmount lock must be held for write
 */
int propagate_umount(struct list_head *list)
{}