crush_reweight_bucket(crush, b);
}
}
+
+void CrushWrapper::encode(bufferlist& bl, bool lean) const
+{
+ assert(crush);
+
+ __u32 magic = CRUSH_MAGIC;
+ ::encode(magic, bl);
+
+ ::encode(crush->max_buckets, bl);
+ ::encode(crush->max_rules, bl);
+ ::encode(crush->max_devices, bl);
+
+ // buckets
+ for (int i=0; i<crush->max_buckets; i++) {
+ __u32 alg = 0;
+ if (crush->buckets[i]) alg = crush->buckets[i]->alg;
+ ::encode(alg, bl);
+ if (!alg)
+ continue;
+
+ ::encode(crush->buckets[i]->id, bl);
+ ::encode(crush->buckets[i]->type, bl);
+ ::encode(crush->buckets[i]->alg, bl);
+ ::encode(crush->buckets[i]->hash, bl);
+ ::encode(crush->buckets[i]->weight, bl);
+ ::encode(crush->buckets[i]->size, bl);
+ for (unsigned j=0; j<crush->buckets[i]->size; j++)
+ ::encode(crush->buckets[i]->items[j], bl);
+
+ switch (crush->buckets[i]->alg) {
+ case CRUSH_BUCKET_UNIFORM:
+ ::encode(((crush_bucket_uniform*)crush->buckets[i])->item_weight, bl);
+ break;
+
+ case CRUSH_BUCKET_LIST:
+ for (unsigned j=0; j<crush->buckets[i]->size; j++) {
+ ::encode(((crush_bucket_list*)crush->buckets[i])->item_weights[j], bl);
+ ::encode(((crush_bucket_list*)crush->buckets[i])->sum_weights[j], bl);
+ }
+ break;
+
+ case CRUSH_BUCKET_TREE:
+ ::encode(((crush_bucket_tree*)crush->buckets[i])->num_nodes, bl);
+ for (unsigned j=0; j<((crush_bucket_tree*)crush->buckets[i])->num_nodes; j++)
+ ::encode(((crush_bucket_tree*)crush->buckets[i])->node_weights[j], bl);
+ break;
+
+ case CRUSH_BUCKET_STRAW:
+ for (unsigned j=0; j<crush->buckets[i]->size; j++) {
+ ::encode(((crush_bucket_straw*)crush->buckets[i])->item_weights[j], bl);
+ ::encode(((crush_bucket_straw*)crush->buckets[i])->straws[j], bl);
+ }
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+ }
+
+ // rules
+ for (unsigned i=0; i<crush->max_rules; i++) {
+ __u32 yes = crush->rules[i] ? 1:0;
+ ::encode(yes, bl);
+ if (!yes)
+ continue;
+
+ ::encode(crush->rules[i]->len, bl);
+ ::encode(crush->rules[i]->mask, bl);
+ for (unsigned j=0; j<crush->rules[i]->len; j++)
+ ::encode(crush->rules[i]->steps[j], bl);
+ }
+
+ // name info
+ ::encode(type_map, bl);
+ ::encode(name_map, bl);
+ ::encode(rule_name_map, bl);
+}
+
+void CrushWrapper::decode(bufferlist::iterator& blp)
+{
+ create();
+
+ __u32 magic;
+ ::decode(magic, blp);
+ if (magic != CRUSH_MAGIC)
+ throw buffer::malformed_input("bad magic number");
+
+ ::decode(crush->max_buckets, blp);
+ ::decode(crush->max_rules, blp);
+ ::decode(crush->max_devices, blp);
+
+ try {
+ // buckets
+ crush->buckets = (crush_bucket**)calloc(1, crush->max_buckets * sizeof(crush_bucket*));
+ for (int i=0; i<crush->max_buckets; i++) {
+ decode_crush_bucket(&crush->buckets[i], blp);
+ }
+
+ // rules
+ crush->rules = (crush_rule**)calloc(1, crush->max_rules * sizeof(crush_rule*));
+ for (unsigned i = 0; i < crush->max_rules; ++i) {
+ __u32 yes;
+ ::decode(yes, blp);
+ if (!yes) {
+ crush->rules[i] = NULL;
+ continue;
+ }
+
+ __u32 len;
+ ::decode(len, blp);
+ crush->rules[i] = (crush_rule*)calloc(1, crush_rule_size(len));
+ crush->rules[i]->len = len;
+ ::decode(crush->rules[i]->mask, blp);
+ for (unsigned j=0; j<crush->rules[i]->len; j++)
+ ::decode(crush->rules[i]->steps[j], blp);
+ }
+
+ // name info
+ ::decode(type_map, blp);
+ ::decode(name_map, blp);
+ ::decode(rule_name_map, blp);
+ build_rmaps();
+
+ finalize();
+ }
+ catch (...) {
+ crush_destroy(crush);
+ throw;
+ }
+}
+
+void CrushWrapper::decode_crush_bucket(crush_bucket** bptr, bufferlist::iterator &blp)
+{
+ __u32 alg;
+ ::decode(alg, blp);
+ if (!alg) {
+ *bptr = NULL;
+ return;
+ }
+
+ int size = 0;
+ switch (alg) {
+ case CRUSH_BUCKET_UNIFORM:
+ size = sizeof(crush_bucket_uniform);
+ break;
+ case CRUSH_BUCKET_LIST:
+ size = sizeof(crush_bucket_list);
+ break;
+ case CRUSH_BUCKET_TREE:
+ size = sizeof(crush_bucket_tree);
+ break;
+ case CRUSH_BUCKET_STRAW:
+ size = sizeof(crush_bucket_straw);
+ break;
+ default:
+ {
+ char str[128];
+ snprintf(str, sizeof(str), "unsupported bucket algorithm: %d", alg);
+ throw buffer::malformed_input(str);
+ }
+ }
+ crush_bucket *bucket = (crush_bucket*)calloc(1, size);
+ *bptr = bucket;
+
+ ::decode(bucket->id, blp);
+ ::decode(bucket->type, blp);
+ ::decode(bucket->alg, blp);
+ ::decode(bucket->hash, blp);
+ ::decode(bucket->weight, blp);
+ ::decode(bucket->size, blp);
+
+ bucket->items = (__s32*)calloc(1, bucket->size * sizeof(__s32));
+ for (unsigned j = 0; j < bucket->size; ++j) {
+ ::decode(bucket->items[j], blp);
+ }
+
+ bucket->perm = (__u32*)calloc(1, bucket->size * sizeof(__s32));
+ bucket->perm_n = 0;
+
+ switch (bucket->alg) {
+ case CRUSH_BUCKET_UNIFORM:
+ ::decode(((crush_bucket_uniform*)bucket)->item_weight, blp);
+ break;
+
+ case CRUSH_BUCKET_LIST: {
+ crush_bucket_list* cbl = (crush_bucket_list*)bucket;
+ cbl->item_weights = (__u32*)calloc(1, bucket->size * sizeof(__u32));
+ cbl->sum_weights = (__u32*)calloc(1, bucket->size * sizeof(__u32));
+
+ for (unsigned j = 0; j < bucket->size; ++j) {
+ ::decode(cbl->item_weights[j], blp);
+ ::decode(cbl->sum_weights[j], blp);
+ }
+ break;
+ }
+
+ case CRUSH_BUCKET_TREE: {
+ crush_bucket_tree* cbt = (crush_bucket_tree*)bucket;
+ ::decode(cbt->num_nodes, blp);
+ cbt->node_weights = (__u32*)calloc(1, cbt->num_nodes * sizeof(__u32));
+ for (unsigned j=0; j<cbt->num_nodes; j++) {
+ ::decode(cbt->node_weights[j], blp);
+ }
+ break;
+ }
+
+ case CRUSH_BUCKET_STRAW: {
+ crush_bucket_straw* cbs = (crush_bucket_straw*)bucket;
+ cbs->straws = (__u32*)calloc(1, bucket->size * sizeof(__u32));
+ cbs->item_weights = (__u32*)calloc(1, bucket->size * sizeof(__u32));
+ for (unsigned j = 0; j < bucket->size; ++j) {
+ ::decode(cbs->item_weights[j], blp);
+ ::decode(cbs->straws[j], blp);
+ }
+ break;
+ }
+
+ default:
+ // We should have handled this case in the first switch statement
+ assert(0);
+ break;
+ }
+}
+
+
+
return bl.write_file(fn);
}
- void encode(bufferlist &bl, bool lean=false) const {
- assert(crush);
-
- __u32 magic = CRUSH_MAGIC;
- ::encode(magic, bl);
-
- ::encode(crush->max_buckets, bl);
- ::encode(crush->max_rules, bl);
- ::encode(crush->max_devices, bl);
-
- // buckets
- for (int i=0; i<crush->max_buckets; i++) {
- __u32 alg = 0;
- if (crush->buckets[i]) alg = crush->buckets[i]->alg;
- ::encode(alg, bl);
- if (!alg) continue;
-
- ::encode(crush->buckets[i]->id, bl);
- ::encode(crush->buckets[i]->type, bl);
- ::encode(crush->buckets[i]->alg, bl);
- ::encode(crush->buckets[i]->hash, bl);
- ::encode(crush->buckets[i]->weight, bl);
- ::encode(crush->buckets[i]->size, bl);
- for (unsigned j=0; j<crush->buckets[i]->size; j++)
- ::encode(crush->buckets[i]->items[j], bl);
-
- switch (crush->buckets[i]->alg) {
- case CRUSH_BUCKET_UNIFORM:
- ::encode(((crush_bucket_uniform*)crush->buckets[i])->item_weight, bl);
- break;
-
- case CRUSH_BUCKET_LIST:
- for (unsigned j=0; j<crush->buckets[i]->size; j++) {
- ::encode(((crush_bucket_list*)crush->buckets[i])->item_weights[j], bl);
- ::encode(((crush_bucket_list*)crush->buckets[i])->sum_weights[j], bl);
- }
- break;
-
- case CRUSH_BUCKET_TREE:
- ::encode(((crush_bucket_tree*)crush->buckets[i])->num_nodes, bl);
- for (unsigned j=0; j<((crush_bucket_tree*)crush->buckets[i])->num_nodes; j++)
- ::encode(((crush_bucket_tree*)crush->buckets[i])->node_weights[j], bl);
- break;
-
- case CRUSH_BUCKET_STRAW:
- for (unsigned j=0; j<crush->buckets[i]->size; j++) {
- ::encode(((crush_bucket_straw*)crush->buckets[i])->item_weights[j], bl);
- ::encode(((crush_bucket_straw*)crush->buckets[i])->straws[j], bl);
- }
- break;
- default:
- assert(0);
- break;
- }
- }
-
- // rules
- for (unsigned i=0; i<crush->max_rules; i++) {
- __u32 yes = crush->rules[i] ? 1:0;
- ::encode(yes, bl);
- if (!yes) continue;
-
- ::encode(crush->rules[i]->len, bl);
- ::encode(crush->rules[i]->mask, bl);
- for (unsigned j=0; j<crush->rules[i]->len; j++)
- ::encode(crush->rules[i]->steps[j], bl);
- }
-
- // name info
- ::encode(type_map, bl);
- ::encode(name_map, bl);
- ::encode(rule_name_map, bl);
- }
-
- void decode(bufferlist::iterator &blp)
- {
- create();
-
- __u32 magic;
- ::decode(magic, blp);
- if (magic != CRUSH_MAGIC)
- throw buffer::malformed_input("bad magic number");
-
- ::decode(crush->max_buckets, blp);
- ::decode(crush->max_rules, blp);
- ::decode(crush->max_devices, blp);
-
- try {
- // buckets
- crush->buckets = (crush_bucket**)calloc(1, crush->max_buckets * sizeof(crush_bucket*));
- for (int i=0; i<crush->max_buckets; i++) {
- decode_crush_bucket(&crush->buckets[i], blp);
- }
-
- // rules
- crush->rules = (crush_rule**)calloc(1, crush->max_rules * sizeof(crush_rule*));
- for (unsigned i = 0; i < crush->max_rules; ++i) {
- __u32 yes;
- ::decode(yes, blp);
- if (!yes) {
- crush->rules[i] = NULL;
- continue;
- }
-
- __u32 len;
- ::decode(len, blp);
- crush->rules[i] = (crush_rule*)calloc(1, crush_rule_size(len));
- crush->rules[i]->len = len;
- ::decode(crush->rules[i]->mask, blp);
- for (unsigned j=0; j<crush->rules[i]->len; j++)
- ::decode(crush->rules[i]->steps[j], blp);
- }
-
- // name info
- ::decode(type_map, blp);
- ::decode(name_map, blp);
- ::decode(rule_name_map, blp);
- build_rmaps();
-
- finalize();
- }
- catch (...) {
- crush_destroy(crush);
- throw;
- }
- }
-
- void decode_crush_bucket(crush_bucket** bptr, bufferlist::iterator &blp)
- {
- __u32 alg;
- ::decode(alg, blp);
- if (!alg) {
- *bptr = NULL;
- return;
- }
-
- int size = 0;
- switch (alg) {
- case CRUSH_BUCKET_UNIFORM:
- size = sizeof(crush_bucket_uniform);
- break;
- case CRUSH_BUCKET_LIST:
- size = sizeof(crush_bucket_list);
- break;
- case CRUSH_BUCKET_TREE:
- size = sizeof(crush_bucket_tree);
- break;
- case CRUSH_BUCKET_STRAW:
- size = sizeof(crush_bucket_straw);
- break;
- default: {
- char str[128];
- snprintf(str, sizeof(str), "unsupported bucket algorithm: %d", alg);
- throw buffer::malformed_input(str);
- }
- }
- crush_bucket *bucket = (crush_bucket*)calloc(1, size);
- *bptr = bucket;
-
- ::decode(bucket->id, blp);
- ::decode(bucket->type, blp);
- ::decode(bucket->alg, blp);
- ::decode(bucket->hash, blp);
- ::decode(bucket->weight, blp);
- ::decode(bucket->size, blp);
-
- bucket->items = (__s32*)calloc(1, bucket->size * sizeof(__s32));
- for (unsigned j = 0; j < bucket->size; ++j) {
- ::decode(bucket->items[j], blp);
- }
-
- bucket->perm = (__u32*)calloc(1, bucket->size * sizeof(__s32));
- bucket->perm_n = 0;
-
- switch (bucket->alg) {
- case CRUSH_BUCKET_UNIFORM: {
- ::decode(((crush_bucket_uniform*)bucket)->item_weight, blp);
- break;
- }
-
- case CRUSH_BUCKET_LIST: {
- crush_bucket_list* cbl = (crush_bucket_list*)bucket;
- cbl->item_weights = (__u32*)calloc(1, bucket->size * sizeof(__u32));
- cbl->sum_weights = (__u32*)calloc(1, bucket->size * sizeof(__u32));
-
- for (unsigned j = 0; j < bucket->size; ++j) {
- ::decode(cbl->item_weights[j], blp);
- ::decode(cbl->sum_weights[j], blp);
- }
- break;
- }
-
- case CRUSH_BUCKET_TREE: {
- crush_bucket_tree* cbt = (crush_bucket_tree*)bucket;
- ::decode(cbt->num_nodes, blp);
- cbt->node_weights = (__u32*)calloc(1, cbt->num_nodes * sizeof(__u32));
- for (unsigned j=0; j<cbt->num_nodes; j++) {
- ::decode(cbt->node_weights[j], blp);
- }
- break;
- }
-
- case CRUSH_BUCKET_STRAW: {
- crush_bucket_straw* cbs = (crush_bucket_straw*)bucket;
- cbs->straws = (__u32*)calloc(1, bucket->size * sizeof(__u32));
- cbs->item_weights = (__u32*)calloc(1, bucket->size * sizeof(__u32));
- for (unsigned j = 0; j < bucket->size; ++j) {
- ::decode(cbs->item_weights[j], blp);
- ::decode(cbs->straws[j], blp);
- }
- break;
- }
-
- default:
- // We should have handled this case in the first switch statement
- assert(0);
- break;
- }
- }
+ void encode(bufferlist &bl, bool lean=false) const;
+ void decode(bufferlist::iterator &blp);
+ void decode_crush_bucket(crush_bucket** bptr, bufferlist::iterator &blp);
};
WRITE_CLASS_ENCODER(CrushWrapper)