1 2 #ifdef __KERNEL__ 3 # include <linux/slab.h> 4 #else 5 # include <stdlib.h> 6 # include <assert.h> 7 # define kfree(x) do { if (x) free(x); } while (0) 8 # define BUG_ON(x) assert(!(x)) 9 #endif 10 11 #include <linux/crush/crush.h> 12 13 const char *crush_bucket_alg_name(int alg) 14 { 15 switch (alg) { 16 case CRUSH_BUCKET_UNIFORM: return "uniform"; 17 case CRUSH_BUCKET_LIST: return "list"; 18 case CRUSH_BUCKET_TREE: return "tree"; 19 case CRUSH_BUCKET_STRAW: return "straw"; 20 case CRUSH_BUCKET_STRAW2: return "straw2"; 21 default: return "unknown"; 22 } 23 } 24 25 /** 26 * crush_get_bucket_item_weight - Get weight of an item in given bucket 27 * @b: bucket pointer 28 * @p: item index in bucket 29 */ 30 int crush_get_bucket_item_weight(const struct crush_bucket *b, int p) 31 { 32 if ((__u32)p >= b->size) 33 return 0; 34 35 switch (b->alg) { 36 case CRUSH_BUCKET_UNIFORM: 37 return ((struct crush_bucket_uniform *)b)->item_weight; 38 case CRUSH_BUCKET_LIST: 39 return ((struct crush_bucket_list *)b)->item_weights[p]; 40 case CRUSH_BUCKET_TREE: 41 return ((struct crush_bucket_tree *)b)->node_weights[crush_calc_tree_node(p)]; 42 case CRUSH_BUCKET_STRAW: 43 return ((struct crush_bucket_straw *)b)->item_weights[p]; 44 case CRUSH_BUCKET_STRAW2: 45 return ((struct crush_bucket_straw2 *)b)->item_weights[p]; 46 } 47 return 0; 48 } 49 50 void crush_destroy_bucket_uniform(struct crush_bucket_uniform *b) 51 { 52 kfree(b->h.perm); 53 kfree(b->h.items); 54 kfree(b); 55 } 56 57 void crush_destroy_bucket_list(struct crush_bucket_list *b) 58 { 59 kfree(b->item_weights); 60 kfree(b->sum_weights); 61 kfree(b->h.perm); 62 kfree(b->h.items); 63 kfree(b); 64 } 65 66 void crush_destroy_bucket_tree(struct crush_bucket_tree *b) 67 { 68 kfree(b->h.perm); 69 kfree(b->h.items); 70 kfree(b->node_weights); 71 kfree(b); 72 } 73 74 void crush_destroy_bucket_straw(struct crush_bucket_straw *b) 75 { 76 kfree(b->straws); 77 kfree(b->item_weights); 78 kfree(b->h.perm); 79 kfree(b->h.items); 80 kfree(b); 81 } 82 83 void crush_destroy_bucket_straw2(struct crush_bucket_straw2 *b) 84 { 85 kfree(b->item_weights); 86 kfree(b->h.perm); 87 kfree(b->h.items); 88 kfree(b); 89 } 90 91 void crush_destroy_bucket(struct crush_bucket *b) 92 { 93 switch (b->alg) { 94 case CRUSH_BUCKET_UNIFORM: 95 crush_destroy_bucket_uniform((struct crush_bucket_uniform *)b); 96 break; 97 case CRUSH_BUCKET_LIST: 98 crush_destroy_bucket_list((struct crush_bucket_list *)b); 99 break; 100 case CRUSH_BUCKET_TREE: 101 crush_destroy_bucket_tree((struct crush_bucket_tree *)b); 102 break; 103 case CRUSH_BUCKET_STRAW: 104 crush_destroy_bucket_straw((struct crush_bucket_straw *)b); 105 break; 106 case CRUSH_BUCKET_STRAW2: 107 crush_destroy_bucket_straw2((struct crush_bucket_straw2 *)b); 108 break; 109 } 110 } 111 112 /** 113 * crush_destroy - Destroy a crush_map 114 * @map: crush_map pointer 115 */ 116 void crush_destroy(struct crush_map *map) 117 { 118 /* buckets */ 119 if (map->buckets) { 120 __s32 b; 121 for (b = 0; b < map->max_buckets; b++) { 122 if (map->buckets[b] == NULL) 123 continue; 124 crush_destroy_bucket(map->buckets[b]); 125 } 126 kfree(map->buckets); 127 } 128 129 /* rules */ 130 if (map->rules) { 131 __u32 b; 132 for (b = 0; b < map->max_rules; b++) 133 crush_destroy_rule(map->rules[b]); 134 kfree(map->rules); 135 } 136 137 kfree(map); 138 } 139 140 void crush_destroy_rule(struct crush_rule *rule) 141 { 142 kfree(rule); 143 } 144