aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pnode.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2025-06-27 23:09:47 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2025-06-29 19:03:30 -0400
commite0f9396e244c0dcc29921ebc3254cb25d6eb31cf (patch)
tree2c050adafe3593c2dbed744b39471481caea831d /fs/pnode.c
parent15e710b8bbb5c537c39ccaa23963d01c76946834 (diff)
downloadtip-e0f9396e244c0dcc29921ebc3254cb25d6eb31cf.tar.gz
propagate_one(): separate the "what should be the master for this copy" part
When we create the first copy for a peer group, it becomes a slave of one of the existing copies; take that logics into a separate helper - find_master(parent, last_copy, original). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/pnode.c')
-rw-r--r--fs/pnode.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/fs/pnode.c b/fs/pnode.c
index 7c832f98595cf8..94de8aad4da567 100644
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -232,6 +232,31 @@ static bool need_secondary(struct mount *m, struct mountpoint *dest_mp)
return true;
}
+static struct mount *find_master(struct mount *m,
+ struct mount *last_copy,
+ struct mount *original)
+{
+ struct mount *p;
+
+ // ascend until there's a copy for something with the same master
+ for (;;) {
+ p = m->mnt_master;
+ if (!p || IS_MNT_MARKED(p))
+ break;
+ m = p;
+ }
+ while (!peers(last_copy, original)) {
+ struct mount *parent = last_copy->mnt_parent;
+ if (parent->mnt_master == p) {
+ if (!peers(parent, m))
+ last_copy = last_copy->mnt_master;
+ break;
+ }
+ last_copy = last_copy->mnt_master;
+ }
+ return last_copy;
+}
+
static int propagate_one(struct mount *m, struct mountpoint *dest_mp)
{
struct mount *child;
@@ -240,23 +265,7 @@ static int propagate_one(struct mount *m, struct mountpoint *dest_mp)
if (peers(m, last_dest)) {
type = CL_MAKE_SHARED;
} else {
- struct mount *n, *p;
- bool done;
- for (n = m; ; n = p) {
- p = n->mnt_master;
- if (!p || IS_MNT_MARKED(p))
- break;
- }
- do {
- struct mount *parent = last_source->mnt_parent;
- if (peers(last_source, first_source))
- break;
- done = parent->mnt_master == p;
- if (done && peers(n, parent))
- break;
- last_source = last_source->mnt_master;
- } while (!done);
-
+ last_source = find_master(m, last_source, first_source);
type = CL_SLAVE;
/* beginning of peer group among the slaves? */
if (IS_MNT_SHARED(m))