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 | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/drivers/md/persistent-data/dm-space-map-checker.c b/drivers/md/persistent-data/dm-space-map-checker.c index 6d7c8329250f..fc90c11620ad 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 @@ | |||
8 | 8 | ||
9 | #include <linux/device-mapper.h> | 9 | #include <linux/device-mapper.h> |
10 | #include <linux/export.h> | 10 | #include <linux/export.h> |
11 | #include <linux/vmalloc.h> | ||
11 | 12 | ||
12 | #ifdef CONFIG_DM_DEBUG_SPACE_MAPS | 13 | #ifdef CONFIG_DM_DEBUG_SPACE_MAPS |
13 | 14 | ||
@@ -89,13 +90,23 @@ static int ca_create(struct count_array *ca, struct dm_space_map *sm) | |||
89 | 90 | ||
90 | ca->nr = nr_blocks; | 91 | ca->nr = nr_blocks; |
91 | ca->nr_free = nr_blocks; | 92 | ca->nr_free = nr_blocks; |
92 | ca->counts = kzalloc(sizeof(*ca->counts) * nr_blocks, GFP_KERNEL); | 93 | |
93 | if (!ca->counts) | 94 | if (!nr_blocks) |
94 | return -ENOMEM; | 95 | ca->counts = NULL; |
96 | else { | ||
97 | ca->counts = vzalloc(sizeof(*ca->counts) * nr_blocks); | ||
98 | if (!ca->counts) | ||
99 | return -ENOMEM; | ||
100 | } | ||
95 | 101 | ||
96 | return 0; | 102 | return 0; |
97 | } | 103 | } |
98 | 104 | ||
105 | static void ca_destroy(struct count_array *ca) | ||
106 | { | ||
107 | vfree(ca->counts); | ||
108 | } | ||
109 | |||
99 | static int ca_load(struct count_array *ca, struct dm_space_map *sm) | 110 | static int ca_load(struct count_array *ca, struct dm_space_map *sm) |
100 | { | 111 | { |
101 | int r; | 112 | int r; |
@@ -126,12 +137,14 @@ static int ca_load(struct count_array *ca, struct dm_space_map *sm) | |||
126 | static int ca_extend(struct count_array *ca, dm_block_t extra_blocks) | 137 | static int ca_extend(struct count_array *ca, dm_block_t extra_blocks) |
127 | { | 138 | { |
128 | dm_block_t nr_blocks = ca->nr + extra_blocks; | 139 | dm_block_t nr_blocks = ca->nr + extra_blocks; |
129 | uint32_t *counts = kzalloc(sizeof(*counts) * nr_blocks, GFP_KERNEL); | 140 | uint32_t *counts = vzalloc(sizeof(*counts) * nr_blocks); |
130 | if (!counts) | 141 | if (!counts) |
131 | return -ENOMEM; | 142 | return -ENOMEM; |
132 | 143 | ||
133 | memcpy(counts, ca->counts, sizeof(*counts) * ca->nr); | 144 | if (ca->counts) { |
134 | kfree(ca->counts); | 145 | memcpy(counts, ca->counts, sizeof(*counts) * ca->nr); |
146 | ca_destroy(ca); | ||
147 | } | ||
135 | ca->nr = nr_blocks; | 148 | ca->nr = nr_blocks; |
136 | ca->nr_free += extra_blocks; | 149 | ca->nr_free += extra_blocks; |
137 | ca->counts = counts; | 150 | ca->counts = counts; |
@@ -151,11 +164,6 @@ static int ca_commit(struct count_array *old, struct count_array *new) | |||
151 | return 0; | 164 | return 0; |
152 | } | 165 | } |
153 | 166 | ||
154 | static void ca_destroy(struct count_array *ca) | ||
155 | { | ||
156 | kfree(ca->counts); | ||
157 | } | ||
158 | |||
159 | /*----------------------------------------------------------------*/ | 167 | /*----------------------------------------------------------------*/ |
160 | 168 | ||
161 | struct sm_checker { | 169 | struct sm_checker { |