diff options
Diffstat (limited to 'fs/btrfs/random-test.c')
-rw-r--r-- | fs/btrfs/random-test.c | 117 |
1 files changed, 99 insertions, 18 deletions
diff --git a/fs/btrfs/random-test.c b/fs/btrfs/random-test.c index cebaf6483927..bbd554e88db2 100644 --- a/fs/btrfs/random-test.c +++ b/fs/btrfs/random-test.c | |||
@@ -142,8 +142,98 @@ error: | |||
142 | return -1; | 142 | return -1; |
143 | } | 143 | } |
144 | 144 | ||
145 | static int empty_tree(struct ctree_root *root, struct radix_tree_root *radix, | ||
146 | int nr) | ||
147 | { | ||
148 | struct ctree_path path; | ||
149 | struct key key; | ||
150 | unsigned long found = 0; | ||
151 | int ret; | ||
152 | int slot; | ||
153 | int *ptr; | ||
154 | int count = 0; | ||
155 | |||
156 | key.offset = 0; | ||
157 | key.flags = 0; | ||
158 | key.objectid = (unsigned long)-1; | ||
159 | while(nr-- >= 0) { | ||
160 | init_path(&path); | ||
161 | ret = search_slot(root, &key, &path, -1); | ||
162 | if (ret < 0) { | ||
163 | release_path(root, &path); | ||
164 | return ret; | ||
165 | } | ||
166 | if (ret != 0) { | ||
167 | if (path.slots[0] == 0) { | ||
168 | release_path(root, &path); | ||
169 | break; | ||
170 | } | ||
171 | path.slots[0] -= 1; | ||
172 | } | ||
173 | slot = path.slots[0]; | ||
174 | found = path.nodes[0]->leaf.items[slot].key.objectid; | ||
175 | ret = del_item(root, &path); | ||
176 | count++; | ||
177 | if (ret) { | ||
178 | fprintf(stderr, | ||
179 | "failed to remove %lu from tree\n", | ||
180 | found); | ||
181 | return -1; | ||
182 | } | ||
183 | release_path(root, &path); | ||
184 | ptr = radix_tree_delete(radix, found); | ||
185 | if (!ptr) | ||
186 | goto error; | ||
187 | if (!keep_running) | ||
188 | break; | ||
189 | } | ||
190 | return 0; | ||
191 | error: | ||
192 | fprintf(stderr, "failed to delete from the radix %lu\n", found); | ||
193 | return -1; | ||
194 | } | ||
195 | |||
196 | static int fill_tree(struct ctree_root *root, struct radix_tree_root *radix, | ||
197 | int count) | ||
198 | { | ||
199 | int i; | ||
200 | int err; | ||
201 | int ret = 0; | ||
202 | for (i = 0; i < count; i++) { | ||
203 | ret = ins_one(root, radix); | ||
204 | if (ret) { | ||
205 | printf("fill failed\n"); | ||
206 | err = ret; | ||
207 | goto out; | ||
208 | } | ||
209 | if (!keep_running) | ||
210 | break; | ||
211 | } | ||
212 | out: | ||
213 | return ret; | ||
214 | } | ||
215 | |||
216 | static int bulk_op(struct ctree_root *root, struct radix_tree_root *radix) | ||
217 | { | ||
218 | int ret; | ||
219 | int nr = rand() % 20000; | ||
220 | static int run_nr = 0; | ||
221 | |||
222 | /* do the bulk op much less frequently */ | ||
223 | if (run_nr++ % 100) | ||
224 | return 0; | ||
225 | ret = empty_tree(root, radix, nr); | ||
226 | if (ret) | ||
227 | return ret; | ||
228 | ret = fill_tree(root, radix, nr); | ||
229 | if (ret) | ||
230 | return ret; | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | |||
145 | int (*ops[])(struct ctree_root *root, struct radix_tree_root *radix) = | 235 | int (*ops[])(struct ctree_root *root, struct radix_tree_root *radix) = |
146 | { ins_one, insert_dup, del_one, lookup_item, lookup_enoent }; | 236 | { ins_one, insert_dup, del_one, lookup_item, lookup_enoent, bulk_op }; |
147 | 237 | ||
148 | static int fill_radix(struct ctree_root *root, struct radix_tree_root *radix) | 238 | static int fill_radix(struct ctree_root *root, struct radix_tree_root *radix) |
149 | { | 239 | { |
@@ -192,7 +282,6 @@ static int fill_radix(struct ctree_root *root, struct radix_tree_root *radix) | |||
192 | } | 282 | } |
193 | return 0; | 283 | return 0; |
194 | } | 284 | } |
195 | |||
196 | void sigstopper(int ignored) | 285 | void sigstopper(int ignored) |
197 | { | 286 | { |
198 | keep_running = 0; | 287 | keep_running = 0; |
@@ -241,22 +330,12 @@ int main(int ac, char **av) | |||
241 | print_usage(); | 330 | print_usage(); |
242 | } | 331 | } |
243 | } | 332 | } |
244 | for (i = 0; i < init_fill_count; i++) { | 333 | printf("initial fill\n"); |
245 | ret = ins_one(root, &radix); | 334 | ret = fill_tree(root, &radix, init_fill_count); |
246 | if (ret) { | 335 | printf("starting run\n"); |
247 | printf("initial fill failed\n"); | 336 | if (ret) { |
248 | err = ret; | 337 | err = ret; |
249 | goto out; | 338 | goto out; |
250 | } | ||
251 | if (i % 10000 == 0) { | ||
252 | printf("initial fill %d level %d count %d\n", i, | ||
253 | node_level(root->node->node.header.flags), | ||
254 | root->node->node.header.nritems); | ||
255 | } | ||
256 | if (keep_running == 0) { | ||
257 | err = 0; | ||
258 | goto out; | ||
259 | } | ||
260 | } | 339 | } |
261 | if (initial_only == 1) { | 340 | if (initial_only == 1) { |
262 | goto out; | 341 | goto out; |
@@ -287,6 +366,8 @@ int main(int ac, char **av) | |||
287 | err = ret; | 366 | err = ret; |
288 | goto out; | 367 | goto out; |
289 | } | 368 | } |
369 | if (ops[op] == bulk_op) | ||
370 | break; | ||
290 | if (keep_running == 0) { | 371 | if (keep_running == 0) { |
291 | err = 0; | 372 | err = 0; |
292 | goto out; | 373 | goto out; |