diff options
Diffstat (limited to 'libglusterfs/src/graph.c')
| -rw-r--r-- | libglusterfs/src/graph.c | 125 | 
1 files changed, 124 insertions, 1 deletions
diff --git a/libglusterfs/src/graph.c b/libglusterfs/src/graph.c index b427740f10f..709ec3b3ce3 100644 --- a/libglusterfs/src/graph.c +++ b/libglusterfs/src/graph.c @@ -515,15 +515,138 @@ glusterfs_graph_prepare (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)          /* XXX: --xlator-option additions */          gf_add_cmdline_options (graph, &ctx->cmd_args); -          return 0;  } +static +xlator_t *glusterfs_root(glusterfs_graph_t *graph) +{ +        return graph->first; +} + +static +int glusterfs_is_leaf(xlator_t *xl) +{ +        int ret = 0; + +        if (!xl->children) +                ret = 1; + +        return ret; +} + +static +uint32_t glusterfs_count_leaves(xlator_t *xl) +{ +        int n = 0; +        xlator_list_t *list = NULL; + +        if (glusterfs_is_leaf(xl)) +                n = 1; +        else +                for (list = xl->children; list; list = list->next) +                        n += glusterfs_count_leaves(list->xlator); + +        return n; +} + +int glusterfs_get_leaf_count(glusterfs_graph_t *graph) +{ +        return graph->leaf_count; +} + +static +int _glusterfs_leaf_position(xlator_t *tgt, int *id, xlator_t *xl) +{ +        xlator_list_t *list = NULL; +        int found = 0; + +        if (xl == tgt) +                found = 1; +        else if (glusterfs_is_leaf(xl)) +                *id += 1; +        else +                for (list = xl->children; !found && list; list = list->next) +                        found = _glusterfs_leaf_position(tgt, id, list->xlator); + +        return found; +} + +int glusterfs_leaf_position(xlator_t *tgt) +{ +        xlator_t *root = NULL; +        int pos = 0; + +        root = glusterfs_root(tgt->graph); + +        if (!_glusterfs_leaf_position(tgt, &pos, root)) +                pos = -1; + +        return pos; +} + +static int +_glusterfs_reachable_leaves(xlator_t *base, xlator_t *xl, dict_t *leaves) +{ +        xlator_list_t *list = NULL; +        int err = 1; +        int pos = 0; +        char strpos[6]; + +        if (glusterfs_is_leaf(xl)) { +                pos = glusterfs_leaf_position(xl); +                if (pos < 0) +                        goto out; +                sprintf(strpos, "%d", pos); + +                err = dict_set_static_ptr(leaves, strpos, base); + +        } else { +                for (err = 0, list = xl->children; +                     !err && list; +                     list = list->next) +                        err = _glusterfs_reachable_leaves(base, list->xlator, +                                                          leaves); +        } + +out: +        return err; +} + +/* + * This function determines which leaves are children (or grandchildren) + * of the given base. The base may have multiple sub volumes. Each sub + * volumes in turn may have sub volumes.. until the leaves are reached. + * Each leaf is numbered 1,2,3,...etc. + * + * The base translator calls this function to see which of *its* subvolumes + * it would forward an FOP to, to *get to* a particular leaf. + * That information is built into the "leaves" dictionary. + * key:destination leaf# -> value:base subvolume xlator. + */ + +int +glusterfs_reachable_leaves(xlator_t *base, dict_t *leaves) +{ +        xlator_list_t *list = NULL; +        int err = 0; + +        for (list = base->children; !err && list; list = list->next) +                err = _glusterfs_reachable_leaves(list->xlator, +                                                  list->xlator, leaves); + +        return err; +}  int  glusterfs_graph_activate (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)  {          int ret = 0; +        xlator_t *root = NULL; + +        root = glusterfs_root(graph); + +        graph->leaf_count = glusterfs_count_leaves(root);          /* XXX: all xlator options validation */          ret = glusterfs_graph_validate_options (graph);  | 
