blob: 13755cdc4fb3d9935e977b540bb004c593d94210 [file] [log] [blame]
Sage Weil5ecc0a02009-10-06 11:31:11 -07001
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 "crush.h"
12
13/**
14 * crush_get_bucket_item_weight - Get weight of an item in given bucket
15 * @b: bucket pointer
16 * @p: item index in bucket
17 */
18int crush_get_bucket_item_weight(struct crush_bucket *b, int p)
19{
20 if (p >= b->size)
21 return 0;
22
23 switch (b->alg) {
24 case CRUSH_BUCKET_UNIFORM:
25 return ((struct crush_bucket_uniform *)b)->item_weight;
26 case CRUSH_BUCKET_LIST:
27 return ((struct crush_bucket_list *)b)->item_weights[p];
28 case CRUSH_BUCKET_TREE:
29 if (p & 1)
30 return ((struct crush_bucket_tree *)b)->node_weights[p];
31 return 0;
32 case CRUSH_BUCKET_STRAW:
33 return ((struct crush_bucket_straw *)b)->item_weights[p];
34 }
35 return 0;
36}
37
38/**
39 * crush_calc_parents - Calculate parent vectors for the given crush map.
40 * @map: crush_map pointer
41 */
42void crush_calc_parents(struct crush_map *map)
43{
44 int i, b, c;
45
46 for (b = 0; b < map->max_buckets; b++) {
47 if (map->buckets[b] == NULL)
48 continue;
49 for (i = 0; i < map->buckets[b]->size; i++) {
50 c = map->buckets[b]->items[i];
51 BUG_ON(c >= map->max_devices ||
52 c < -map->max_buckets);
53 if (c >= 0)
54 map->device_parents[c] = map->buckets[b]->id;
55 else
56 map->bucket_parents[-1-c] = map->buckets[b]->id;
57 }
58 }
59}
60
61void crush_destroy_bucket_uniform(struct crush_bucket_uniform *b)
62{
63 kfree(b->h.perm);
64 kfree(b->h.items);
65 kfree(b);
66}
67
68void crush_destroy_bucket_list(struct crush_bucket_list *b)
69{
70 kfree(b->item_weights);
71 kfree(b->sum_weights);
72 kfree(b->h.perm);
73 kfree(b->h.items);
74 kfree(b);
75}
76
77void crush_destroy_bucket_tree(struct crush_bucket_tree *b)
78{
79 kfree(b->node_weights);
80 kfree(b);
81}
82
83void crush_destroy_bucket_straw(struct crush_bucket_straw *b)
84{
85 kfree(b->straws);
86 kfree(b->item_weights);
87 kfree(b->h.perm);
88 kfree(b->h.items);
89 kfree(b);
90}
91
92void crush_destroy_bucket(struct crush_bucket *b)
93{
94 switch (b->alg) {
95 case CRUSH_BUCKET_UNIFORM:
96 crush_destroy_bucket_uniform((struct crush_bucket_uniform *)b);
97 break;
98 case CRUSH_BUCKET_LIST:
99 crush_destroy_bucket_list((struct crush_bucket_list *)b);
100 break;
101 case CRUSH_BUCKET_TREE:
102 crush_destroy_bucket_tree((struct crush_bucket_tree *)b);
103 break;
104 case CRUSH_BUCKET_STRAW:
105 crush_destroy_bucket_straw((struct crush_bucket_straw *)b);
106 break;
107 }
108}
109
110/**
111 * crush_destroy - Destroy a crush_map
112 * @map: crush_map pointer
113 */
114void crush_destroy(struct crush_map *map)
115{
116 int b;
117
118 /* buckets */
119 if (map->buckets) {
120 for (b = 0; b < map->max_buckets; b++) {
121 if (map->buckets[b] == NULL)
122 continue;
123 crush_destroy_bucket(map->buckets[b]);
124 }
125 kfree(map->buckets);
126 }
127
128 /* rules */
129 if (map->rules) {
130 for (b = 0; b < map->max_rules; b++)
131 kfree(map->rules[b]);
132 kfree(map->rules);
133 }
134
135 kfree(map->bucket_parents);
136 kfree(map->device_parents);
137 kfree(map);
138}
139
140