Skip to content

Commit d8cc036

Browse files
author
Al Viro
committed
fix propagation graph breakage by MOVE_MOUNT_SET_GROUP move_mount(2)
9ffb14e "move_mount: allow to add a mount into an existing group" breaks assertions on ->mnt_share/->mnt_slave. For once, the data structures in question are actually documented. Documentation/filesystem/sharedsubtree.rst: All vfsmounts in a peer group have the same ->mnt_master. If it is non-NULL, they form a contiguous (ordered) segment of slave list. do_set_group() puts a mount into the same place in propagation graph as the old one. As the result, if old mount gets events from somewhere and is not a pure event sink, new one needs to be placed next to the old one in the slave list the old one's on. If it is a pure event sink, we only need to make sure the new one doesn't end up in the middle of some peer group. "move_mount: allow to add a mount into an existing group" ends up putting the new one in the beginning of list; that's definitely not going to be in the middle of anything, so that's fine for case when old is not marked shared. In case when old one _is_ marked shared (i.e. is not a pure event sink), that breaks the assumptions of propagation graph iterators. Put the new mount next to the old one on the list - that does the right thing in "old is marked shared" case and is just as correct as the current behaviour if old is not marked shared (kudos to Pavel for pointing that out - my original suggested fix changed behaviour in the "nor marked" case, which complicated things for no good reason). Reviewed-by: Christian Brauner <brauner@kernel.org> Fixes: 9ffb14e ("move_mount: allow to add a mount into an existing group") Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent bab77c0 commit d8cc036

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

fs/namespace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3453,7 +3453,7 @@ static int do_set_group(struct path *from_path, struct path *to_path)
34533453
if (IS_MNT_SLAVE(from)) {
34543454
struct mount *m = from->mnt_master;
34553455

3456-
list_add(&to->mnt_slave, &m->mnt_slave_list);
3456+
list_add(&to->mnt_slave, &from->mnt_slave);
34573457
to->mnt_master = m;
34583458
}
34593459

0 commit comments

Comments
 (0)