fs/pnode.c

Source file repositories/reference/linux-study-clean/fs/pnode.c

File Facts

System
Linux kernel
Corpus path
fs/pnode.c
Extension
.c
Size
17383 bytes
Lines
688
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (list_empty(&mnt->mnt_share)) {
			mnt_release_group_id(mnt);
		} else {
			m = next_peer(mnt);
			list_del_init(&mnt->mnt_share);
			mnt->mnt_group_id = 0;
		}
		CLEAR_MNT_SHARED(mnt);
		transfer_propagation(mnt, m);
	}
	hlist_del_init(&mnt->mnt_slave);
	if (type == MS_SLAVE) {
		mnt->mnt_master = m;
		if (m)
			hlist_add_head(&mnt->mnt_slave, &m->mnt_slave_list);
	} else {
		mnt->mnt_master = NULL;
		if (type == MS_UNBINDABLE)
			mnt->mnt_t_flags |= T_UNBINDABLE;
		else
			mnt->mnt_t_flags &= ~T_UNBINDABLE;
	}
}

static struct mount *trace_transfers(struct mount *m)
{
	while (1) {
		struct mount *next = next_peer(m);

		if (next != m) {
			list_del_init(&m->mnt_share);
			m->mnt_group_id = 0;
			m->mnt_master = next;
		} else {
			if (IS_MNT_SHARED(m))
				mnt_release_group_id(m);
			next = m->mnt_master;
		}
		hlist_del_init(&m->mnt_slave);
		CLEAR_MNT_SHARED(m);
		SET_MNT_MARK(m);

		if (!next || !will_be_unmounted(next))
			return next;
		if (IS_MNT_MARKED(next))
			return next->mnt_master;
		m = next;
	}
}

static void set_destinations(struct mount *m, struct mount *master)
{
	struct mount *next;

	while ((next = m->mnt_master) != master) {
		m->mnt_master = master;
		m = next;
	}
}

void bulk_make_private(struct list_head *set)
{
	struct mount *m;

	list_for_each_entry(m, set, mnt_list)
		if (!IS_MNT_MARKED(m))
			set_destinations(m, trace_transfers(m));

	list_for_each_entry(m, set, mnt_list) {
		transfer_propagation(m, m->mnt_master);
		m->mnt_master = NULL;
		CLEAR_MNT_MARK(m);
	}
}

static struct mount *__propagation_next(struct mount *m,
					 struct mount *origin)
{
	while (1) {
		struct mount *master = m->mnt_master;

		if (master == origin->mnt_master) {
			struct mount *next = next_peer(m);
			return (next == origin) ? NULL : next;
		} else if (m->mnt_slave.next)
			return next_slave(m);

		/* back at master */
		m = master;
	}

Annotation

Implementation Notes