diff options
Diffstat (limited to 'drivers/md/persistent-data/dm-space-map-checker.c')
| -rw-r--r-- | drivers/md/persistent-data/dm-space-map-checker.c | 54 | 
1 files changed, 31 insertions, 23 deletions
diff --git a/drivers/md/persistent-data/dm-space-map-checker.c b/drivers/md/persistent-data/dm-space-map-checker.c index 50ed53bf4aa..fc90c11620a 100644 --- a/drivers/md/persistent-data/dm-space-map-checker.c +++ b/drivers/md/persistent-data/dm-space-map-checker.c @@ -8,6 +8,7 @@  #include <linux/device-mapper.h>  #include <linux/export.h> +#include <linux/vmalloc.h>  #ifdef CONFIG_DM_DEBUG_SPACE_MAPS @@ -89,13 +90,23 @@ static int ca_create(struct count_array *ca, struct dm_space_map *sm)  	ca->nr = nr_blocks;  	ca->nr_free = nr_blocks; -	ca->counts = kzalloc(sizeof(*ca->counts) * nr_blocks, GFP_KERNEL); -	if (!ca->counts) -		return -ENOMEM; + +	if (!nr_blocks) +		ca->counts = NULL; +	else { +		ca->counts = vzalloc(sizeof(*ca->counts) * nr_blocks); +		if (!ca->counts) +			return -ENOMEM; +	}  	return 0;  } +static void ca_destroy(struct count_array *ca) +{ +	vfree(ca->counts); +} +  static int ca_load(struct count_array *ca, struct dm_space_map *sm)  {  	int r; @@ -126,12 +137,14 @@ static int ca_load(struct count_array *ca, struct dm_space_map *sm)  static int ca_extend(struct count_array *ca, dm_block_t extra_blocks)  {  	dm_block_t nr_blocks = ca->nr + extra_blocks; -	uint32_t *counts = kzalloc(sizeof(*counts) * nr_blocks, GFP_KERNEL); +	uint32_t *counts = vzalloc(sizeof(*counts) * nr_blocks);  	if (!counts)  		return -ENOMEM; -	memcpy(counts, ca->counts, sizeof(*counts) * ca->nr); -	kfree(ca->counts); +	if (ca->counts) { +		memcpy(counts, ca->counts, sizeof(*counts) * ca->nr); +		ca_destroy(ca); +	}  	ca->nr = nr_blocks;  	ca->nr_free += extra_blocks;  	ca->counts = counts; @@ -151,11 +164,6 @@ static int ca_commit(struct count_array *old, struct count_array *new)  	return 0;  } -static void ca_destroy(struct count_array *ca) -{ -	kfree(ca->counts); -} -  /*----------------------------------------------------------------*/  struct sm_checker { @@ -343,25 +351,25 @@ struct dm_space_map *dm_sm_checker_create(struct dm_space_map *sm)  	int r;  	struct sm_checker *smc; -	if (!sm) -		return NULL; +	if (IS_ERR_OR_NULL(sm)) +		return ERR_PTR(-EINVAL);  	smc = kmalloc(sizeof(*smc), GFP_KERNEL);  	if (!smc) -		return NULL; +		return ERR_PTR(-ENOMEM);  	memcpy(&smc->sm, &ops_, sizeof(smc->sm));  	r = ca_create(&smc->old_counts, sm);  	if (r) {  		kfree(smc); -		return NULL; +		return ERR_PTR(r);  	}  	r = ca_create(&smc->counts, sm);  	if (r) {  		ca_destroy(&smc->old_counts);  		kfree(smc); -		return NULL; +		return ERR_PTR(r);  	}  	smc->real_sm = sm; @@ -371,7 +379,7 @@ struct dm_space_map *dm_sm_checker_create(struct dm_space_map *sm)  		ca_destroy(&smc->counts);  		ca_destroy(&smc->old_counts);  		kfree(smc); -		return NULL; +		return ERR_PTR(r);  	}  	r = ca_commit(&smc->old_counts, &smc->counts); @@ -379,7 +387,7 @@ struct dm_space_map *dm_sm_checker_create(struct dm_space_map *sm)  		ca_destroy(&smc->counts);  		ca_destroy(&smc->old_counts);  		kfree(smc); -		return NULL; +		return ERR_PTR(r);  	}  	return &smc->sm; @@ -391,25 +399,25 @@ struct dm_space_map *dm_sm_checker_create_fresh(struct dm_space_map *sm)  	int r;  	struct sm_checker *smc; -	if (!sm) -		return NULL; +	if (IS_ERR_OR_NULL(sm)) +		return ERR_PTR(-EINVAL);  	smc = kmalloc(sizeof(*smc), GFP_KERNEL);  	if (!smc) -		return NULL; +		return ERR_PTR(-ENOMEM);  	memcpy(&smc->sm, &ops_, sizeof(smc->sm));  	r = ca_create(&smc->old_counts, sm);  	if (r) {  		kfree(smc); -		return NULL; +		return ERR_PTR(r);  	}  	r = ca_create(&smc->counts, sm);  	if (r) {  		ca_destroy(&smc->old_counts);  		kfree(smc); -		return NULL; +		return ERR_PTR(r);  	}  	smc->real_sm = sm;  |