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