2009-10-06 22:31:11 +04:00
# ifdef __KERNEL__
# include <linux / slab.h>
# else
# include <stdlib.h>
# include <assert.h>
# define kfree(x) do { if (x) free(x); } while (0)
# define BUG_ON(x) assert(!(x))
# endif
2010-04-07 02:14:15 +04:00
# include <linux/crush/crush.h>
2009-10-06 22:31:11 +04:00
2009-11-07 03:39:26 +03:00
const char * crush_bucket_alg_name ( int alg )
{
switch ( alg ) {
case CRUSH_BUCKET_UNIFORM : return " uniform " ;
case CRUSH_BUCKET_LIST : return " list " ;
case CRUSH_BUCKET_TREE : return " tree " ;
case CRUSH_BUCKET_STRAW : return " straw " ;
default : return " unknown " ;
}
}
2009-10-06 22:31:11 +04:00
/**
* crush_get_bucket_item_weight - Get weight of an item in given bucket
* @ b : bucket pointer
* @ p : item index in bucket
*/
2012-05-08 02:38:35 +04:00
int crush_get_bucket_item_weight ( const struct crush_bucket * b , int p )
2009-10-06 22:31:11 +04:00
{
2012-05-08 02:38:35 +04:00
if ( ( __u32 ) p > = b - > size )
2009-10-06 22:31:11 +04:00
return 0 ;
switch ( b - > alg ) {
case CRUSH_BUCKET_UNIFORM :
return ( ( struct crush_bucket_uniform * ) b ) - > item_weight ;
case CRUSH_BUCKET_LIST :
return ( ( struct crush_bucket_list * ) b ) - > item_weights [ p ] ;
case CRUSH_BUCKET_TREE :
2012-05-08 02:36:49 +04:00
return ( ( struct crush_bucket_tree * ) b ) - > node_weights [ crush_calc_tree_node ( p ) ] ;
2009-10-06 22:31:11 +04:00
case CRUSH_BUCKET_STRAW :
return ( ( struct crush_bucket_straw * ) b ) - > item_weights [ p ] ;
}
return 0 ;
}
void crush_destroy_bucket_uniform ( struct crush_bucket_uniform * b )
{
kfree ( b - > h . perm ) ;
kfree ( b - > h . items ) ;
kfree ( b ) ;
}
void crush_destroy_bucket_list ( struct crush_bucket_list * b )
{
kfree ( b - > item_weights ) ;
kfree ( b - > sum_weights ) ;
kfree ( b - > h . perm ) ;
kfree ( b - > h . items ) ;
kfree ( b ) ;
}
void crush_destroy_bucket_tree ( struct crush_bucket_tree * b )
{
2012-05-08 02:37:05 +04:00
kfree ( b - > h . perm ) ;
kfree ( b - > h . items ) ;
2009-10-06 22:31:11 +04:00
kfree ( b - > node_weights ) ;
kfree ( b ) ;
}
void crush_destroy_bucket_straw ( struct crush_bucket_straw * b )
{
kfree ( b - > straws ) ;
kfree ( b - > item_weights ) ;
kfree ( b - > h . perm ) ;
kfree ( b - > h . items ) ;
kfree ( b ) ;
}
void crush_destroy_bucket ( struct crush_bucket * b )
{
switch ( b - > alg ) {
case CRUSH_BUCKET_UNIFORM :
crush_destroy_bucket_uniform ( ( struct crush_bucket_uniform * ) b ) ;
break ;
case CRUSH_BUCKET_LIST :
crush_destroy_bucket_list ( ( struct crush_bucket_list * ) b ) ;
break ;
case CRUSH_BUCKET_TREE :
crush_destroy_bucket_tree ( ( struct crush_bucket_tree * ) b ) ;
break ;
case CRUSH_BUCKET_STRAW :
crush_destroy_bucket_straw ( ( struct crush_bucket_straw * ) b ) ;
break ;
}
}
/**
* crush_destroy - Destroy a crush_map
* @ map : crush_map pointer
*/
void crush_destroy ( struct crush_map * map )
{
/* buckets */
if ( map - > buckets ) {
2012-05-08 02:38:35 +04:00
__s32 b ;
2009-10-06 22:31:11 +04:00
for ( b = 0 ; b < map - > max_buckets ; b + + ) {
if ( map - > buckets [ b ] = = NULL )
continue ;
crush_destroy_bucket ( map - > buckets [ b ] ) ;
}
kfree ( map - > buckets ) ;
}
/* rules */
if ( map - > rules ) {
2012-05-08 02:38:35 +04:00
__u32 b ;
2009-10-06 22:31:11 +04:00
for ( b = 0 ; b < map - > max_rules ; b + + )
kfree ( map - > rules [ b ] ) ;
kfree ( map - > rules ) ;
}
kfree ( map ) ;
}