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