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