Blame SOURCES/autofs-5.1.7-add-tree_mapent_traverse_subtree.patch

29d2b9
autofs-5.1.7 - add tree_mapent_traverse_subtree()
29d2b9
29d2b9
From: Ian Kent <raven@themaw.net>
29d2b9
29d2b9
Add function tree_mapent_traverse_subtree() that enumerates offsets from
29d2b9
a given base node bounded by subtree nesting points.
29d2b9
29d2b9
Signed-off-by: Ian Kent <raven@themaw.net>
29d2b9
---
29d2b9
 CHANGELOG    |    1 +
29d2b9
 lib/mounts.c |   47 +++++++++++++++++++++++++++++++++++++++++++++++
29d2b9
 2 files changed, 48 insertions(+)
29d2b9
29d2b9
diff --git a/CHANGELOG b/CHANGELOG
29d2b9
index 488b4996..390028ac 100644
29d2b9
--- a/CHANGELOG
29d2b9
+++ b/CHANGELOG
29d2b9
@@ -35,6 +35,7 @@
29d2b9
 - add mapent tree implementation.
29d2b9
 - add tree_mapent_add_node().
29d2b9
 - add tree_mapent_delete_offsets().
29d2b9
+- add tree_mapent_traverse_subtree().
29d2b9
 
29d2b9
 25/01/2021 autofs-5.1.7
29d2b9
 - make bind mounts propagation slave by default.
29d2b9
diff --git a/lib/mounts.c b/lib/mounts.c
29d2b9
index eb700c79..fded4c09 100644
29d2b9
--- a/lib/mounts.c
29d2b9
+++ b/lib/mounts.c
29d2b9
@@ -1528,6 +1528,53 @@ int tree_mapent_add_node(struct mapent_cache *mc,
29d2b9
 	return 1;
29d2b9
 }
29d2b9
 
29d2b9
+static inline int tree_mapent_is_root(struct mapent *oe)
29d2b9
+{
29d2b9
+	/* Offset "/" is a special case, it's looked up and mounted
29d2b9
+	 * seperately because the offset tree may or may not have a
29d2b9
+	 * real mount at the base and the triggers inside it need to
29d2b9
+	 * be mounted in either case. Also the order requires the
29d2b9
+	 * offset at the top of the (sub)tree to be handled after
29d2b9
+	 * the traversal.
29d2b9
+	 */
29d2b9
+	return (oe->key[oe->len - 1] == '/' ||
29d2b9
+	        MAPENT_ROOT(oe) == MAPENT_NODE(oe));
29d2b9
+}
29d2b9
+
29d2b9
+struct traverse_subtree_context {
29d2b9
+	struct autofs_point *ap;
29d2b9
+	struct tree_node *base;
29d2b9
+	int strict;
29d2b9
+};
29d2b9
+
29d2b9
+static int tree_mapent_traverse_subtree(struct tree_node *n, tree_work_fn_t work, void *ptr)
29d2b9
+{
29d2b9
+	struct traverse_subtree_context *ctxt = ptr;
29d2b9
+	struct mapent *oe = MAPENT(n);
29d2b9
+	int ret = 1;
29d2b9
+
29d2b9
+	if (n->left) {
29d2b9
+		ret = tree_mapent_traverse_subtree(n->left, work, ctxt);
29d2b9
+		if (!ret && ctxt->strict)
29d2b9
+			goto done;
29d2b9
+	}
29d2b9
+
29d2b9
+	/* Node is not multi-mount root and is part of current subtree */
29d2b9
+	if (!tree_mapent_is_root(oe) && MAPENT_PARENT(oe) == ctxt->base) {
29d2b9
+		ret = work(n, ctxt);
29d2b9
+		if (!ret && ctxt->strict)
29d2b9
+			goto done;
29d2b9
+	}
29d2b9
+
29d2b9
+	if (n->right) {
29d2b9
+		ret = tree_mapent_traverse_subtree(n->right, work, ctxt);
29d2b9
+		if (!ret && ctxt->strict)
29d2b9
+			goto done;
29d2b9
+	}
29d2b9
+done:
29d2b9
+	return ret;
29d2b9
+}
29d2b9
+
29d2b9
 static int tree_mapent_delete_offset_tree(struct tree_node *root)
29d2b9
 {
29d2b9
 	struct mapent *me = MAPENT(root);