Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4b1d0d3e authored by Daniel Rosenberg's avatar Daniel Rosenberg
Browse files

ANDROID: mnt: Propagate remount correctly



This switches over to propagation_next to respect
namepsace semantics.

Test: Remounting to change the options of a fs with mount based
      options should propagate to all shared copies of that mount,
      and the slaves/indirect slaves of those.
Bug: 122428178
Signed-off-by: default avatarDaniel Rosenberg <drosen@google.com>
Change-Id: Ic35cd2782a646435689f5bedfa1f218fe4ab8254
parent 8536e3e9
Loading
Loading
Loading
Loading
+8 −26
Original line number Diff line number Diff line
@@ -610,36 +610,18 @@ int propagate_umount(struct list_head *list)
	return 0;
}

/*
 *  Iterates over all slaves, and slaves of slaves.
 */
static struct mount *next_descendent(struct mount *root, struct mount *cur)
{
	if (!IS_MNT_NEW(cur) && !list_empty(&cur->mnt_slave_list))
		return first_slave(cur);
	do {
		struct mount *master = cur->mnt_master;

		if (!master || cur->mnt_slave.next != &master->mnt_slave_list) {
			struct mount *next = next_slave(cur);

			return (next == root) ? NULL : next;
		}
		cur = master;
	} while (cur != root);
	return NULL;
}

void propagate_remount(struct mount *mnt)
{
	struct mount *m = mnt;
	struct mount *parent = mnt->mnt_parent;
	struct mount *p = mnt, *m;
	struct super_block *sb = mnt->mnt.mnt_sb;

	if (sb->s_op->copy_mnt_data) {
		m = next_descendent(mnt, m);
		while (m) {
	if (!sb->s_op->copy_mnt_data)
		return;
	for (p = propagation_next(parent, parent); p;
				p = propagation_next(p, parent)) {
		m = __lookup_mnt(&p->mnt, mnt->mnt_mountpoint);
		if (m)
			sb->s_op->copy_mnt_data(m->mnt.data, mnt->mnt.data);
			m = next_descendent(mnt, m);
		}
	}
}