static int calc_depth(int size)
{
+ if (size == 0) {
+ return 0;
+ }
+
int depth = 1;
int t = size - 1;
while (t) {
bucket->h.type = type;
bucket->h.size = size;
+ if (size == 0) {
+ bucket->h.items = NULL;
+ bucket->h.perm = NULL;
+ bucket->h.weight = 0;
+ bucket->node_weights = NULL;
+ bucket->num_nodes = 0;
+ /* printf("size 0 depth 0 nodes 0\n"); */
+ return bucket;
+ }
+
bucket->h.items = malloc(sizeof(__s32)*size);
if (!bucket->h.items)
goto err;
node = crush_calc_tree_node(newsize-1);
bucket->node_weights[node] = weight;
+ /* if the depth increase, we need to initialize the new root node's weight before add bucket item */
+ int root = bucket->num_nodes/2;
+ if (depth >= 2 && (node - 1) == root) {
+ /* if the new item is the first node in right sub tree, so
+ * the root node initial weight is left sub tree's weight
+ */
+ bucket->node_weights[root] = bucket->node_weights[root/2];
+ }
+
for (j=1; j<depth; j++) {
node = parent(node);
- if (!crush_addition_is_unsafe(bucket->node_weights[node], weight))
+ if (crush_addition_is_unsafe(bucket->node_weights[node], weight))
return -ERANGE;
bucket->node_weights[node] += weight;
if (crush_addition_is_unsafe(bucket->h.weight, weight))
return -ERANGE;
+ bucket->h.items[newsize-1] = item;
bucket->h.weight += weight;
bucket->h.size++;
--- /dev/null
+ $ crushtool -i "$TESTDIR/tree.template" --add-item 0 1.0 device0 --loc host host0 --loc cluster cluster0 -o one > /dev/null
+ $ crushtool -i one --add-item 1 1.0 device1 --loc host host0 --loc cluster cluster0 -o two > /dev/null
+ $ crushtool -i two --add-item 2 1.0 device2 --loc host host0 --loc cluster cluster0 -o tree > /dev/null
+ $ crushtool -i tree --add-item 3 1.0 device3 --loc host host0 --loc cluster cluster0 -o four > /dev/null
+ $ crushtool -i four --add-item 4 1.0 device4 --loc host host0 --loc cluster cluster0 -o five > /dev/null
+ $ crushtool -i five --add-item 5 1.0 device5 --loc host host0 --loc cluster cluster0 -o six > /dev/null
+ $ crushtool -i six --add-item 6 1.0 device6 --loc host host0 --loc cluster cluster0 -o seven > /dev/null
+ $ crushtool -i seven --add-item 7 1.0 device7 --loc host host0 --loc cluster cluster0 -o eight > /dev/null
+ $ crushtool -d eight -o final
+ $ cmp final "$TESTDIR/tree.template.final"
--- /dev/null
+# begin crush map
+
+# devices
+device 0 device0
+device 1 device1
+device 2 device2
+device 3 device3
+device 4 device4
+device 5 device5
+device 6 device6
+device 7 device7
+
+# types
+type 0 device
+type 1 host
+type 2 cluster
+
+# buckets
+host host0 {
+ id -2 # do not change unnecessarily
+ # weight 8.000
+ alg tree # do not change pos for existing items unnecessarily
+ hash 0 # rjenkins1
+ item device0 weight 1.000 pos 0
+ item device1 weight 1.000 pos 1
+ item device2 weight 1.000 pos 2
+ item device3 weight 1.000 pos 3
+ item device4 weight 1.000 pos 4
+ item device5 weight 1.000 pos 5
+ item device6 weight 1.000 pos 6
+ item device7 weight 1.000 pos 7
+}
+cluster cluster0 {
+ id -1 # do not change unnecessarily
+ # weight 8.000
+ alg tree # do not change pos for existing items unnecessarily
+ hash 0 # rjenkins1
+ item host0 weight 8.000 pos 0
+}
+
+# rules
+rule data {
+ ruleset 0
+ type replicated
+ min_size 1
+ max_size 10
+ step take cluster0
+ step chooseleaf firstn 0 type host
+ step emit
+}
+rule metadata {
+ ruleset 1
+ type replicated
+ min_size 1
+ max_size 10
+ step take cluster0
+ step chooseleaf firstn 0 type host
+ step emit
+}
+rule rbd {
+ ruleset 2
+ type replicated
+ min_size 1
+ max_size 10
+ step take cluster0
+ step chooseleaf firstn 0 type host
+ step emit
+}
+
+# end crush map