summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/graph.c
diff options
context:
space:
mode:
authorDan Lambright <dlambrig@redhat.com>2015-02-18 14:49:50 -0500
committerVijay Bellur <vbellur@redhat.com>2015-03-18 04:47:41 -0700
commita216745e5db3fdb4fa8d625c971e70f8d0e34d23 (patch)
treec1165dbc612ec7121bd1734cb9bb006f9ac7c9d3 /libglusterfs/src/graph.c
parent38ccaaf9d1a93c4fc6d733ee3bd5c73e5457bdab (diff)
cluster/dht: Change the subvolume encoding in d_off to be a "global"
position in the graph rather than relative (local) to a particular translator. Encoding the volume in this way allows a single translator to manage which brick is currently being scanned for directory entries. Using a single translator minimizes allocated bits in the d_off. It also allows multiple DHT translators in the same graph to have a common frame of reference (the graph position) for which brick is being read. Multiple DHT translators are needed for the Tiering feature. The fix builds off a previous change (9332) which removed subvolume encoding from AFR. The fix makes an equivalent change to the EC translator. More background can be found in fix 9332 and gluster-dev discussions [1]. DHT and AFR/EC are responsibile (as before) for choosing which brick to enumerate directory entries in over the readdir lifecycle. The client translator receiving the readdir fop encodes the dht_t. It is referred to as the "leaf node" in the graph and corresponds to the brick being scanned. When DHT decodes the d_off, it translates the leaf node to a local subvolume, which represents the next node in the graph leading to the brick. Tracking of leaf nodes is done in common utility functions. Leaf nodes counts and positional information are updated on a graph switch. [1] www.gluster.org/pipermail/gluster-devel/2015-January/043592.html Change-Id: Iaf0ea86d7046b1ceadbad69d88707b243077ebc8 BUG: 1190734 Signed-off-by: Dan Lambright <dlambrig@redhat.com> Reviewed-on: http://review.gluster.org/9688 Reviewed-by: Xavier Hernandez <xhernandez@datalab.es> Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com> Tested-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'libglusterfs/src/graph.c')
-rw-r--r--libglusterfs/src/graph.c125
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);