aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/random-test.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-03-21 11:12:56 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-03-21 11:12:56 -0400
commit2e635a278354a1a7951e16cfea4c247d6d0e7c99 (patch)
tree4b94d54ddcd7cb184681260738b68caef4edee81 /fs/btrfs/random-test.c
parent1261ec42b3d3a3ad878bd172144940e3ac710749 (diff)
Btrfs: initial move to kernel module land
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/random-test.c')
-rw-r--r--fs/btrfs/random-test.c405
1 files changed, 0 insertions, 405 deletions
diff --git a/fs/btrfs/random-test.c b/fs/btrfs/random-test.c
deleted file mode 100644
index 3a38ae7a886d..000000000000
--- a/fs/btrfs/random-test.c
+++ /dev/null
@@ -1,405 +0,0 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <signal.h>
4#include "kerncompat.h"
5#include "radix-tree.h"
6#include "ctree.h"
7#include "disk-io.h"
8#include "print-tree.h"
9#include "transaction.h"
10
11int keep_running = 1;
12struct btrfs_super_block super;
13
14static int setup_key(struct radix_tree_root *root, struct btrfs_key *key,
15 int exists)
16{
17 int num = rand();
18 unsigned long res[2];
19 int ret;
20
21 key->flags = 0;
22 btrfs_set_key_type(key, BTRFS_STRING_ITEM_KEY);
23 key->offset = 0;
24again:
25 ret = radix_tree_gang_lookup(root, (void **)res, num, 2);
26 if (exists) {
27 if (ret == 0)
28 return -1;
29 num = res[0];
30 } else if (ret != 0 && num == res[0]) {
31 num++;
32 if (ret > 1 && num == res[1]) {
33 num++;
34 goto again;
35 }
36 }
37 key->objectid = num;
38 return 0;
39}
40
41static int ins_one(struct btrfs_trans_handle *trans, struct btrfs_root *root,
42 struct radix_tree_root *radix)
43{
44 struct btrfs_path path;
45 struct btrfs_key key;
46 int ret;
47 char buf[128];
48 unsigned long oid;
49 btrfs_init_path(&path);
50 ret = setup_key(radix, &key, 0);
51 sprintf(buf, "str-%Lu\n", key.objectid);
52 ret = btrfs_insert_item(trans, root, &key, buf, strlen(buf));
53 if (ret)
54 goto error;
55 oid = (unsigned long)key.objectid;
56 radix_tree_preload(GFP_KERNEL);
57 ret = radix_tree_insert(radix, oid, (void *)oid);
58 radix_tree_preload_end();
59 if (ret)
60 goto error;
61 return ret;
62error:
63 printf("failed to insert %Lu\n", key.objectid);
64 return -1;
65}
66
67static int insert_dup(struct btrfs_trans_handle *trans, struct btrfs_root
68 *root, struct radix_tree_root *radix)
69{
70 struct btrfs_path path;
71 struct btrfs_key key;
72 int ret;
73 char buf[128];
74 btrfs_init_path(&path);
75 ret = setup_key(radix, &key, 1);
76 if (ret < 0)
77 return 0;
78 sprintf(buf, "str-%Lu\n", key.objectid);
79 ret = btrfs_insert_item(trans, root, &key, buf, strlen(buf));
80 if (ret != -EEXIST) {
81 printf("insert on %Lu gave us %d\n", key.objectid, ret);
82 return 1;
83 }
84 return 0;
85}
86
87static int del_one(struct btrfs_trans_handle *trans, struct btrfs_root *root,
88 struct radix_tree_root *radix)
89{
90 struct btrfs_path path;
91 struct btrfs_key key;
92 int ret;
93 unsigned long *ptr;
94 btrfs_init_path(&path);
95 ret = setup_key(radix, &key, 1);
96 if (ret < 0)
97 return 0;
98 ret = btrfs_search_slot(trans, root, &key, &path, -1, 1);
99 if (ret)
100 goto error;
101 ret = btrfs_del_item(trans, root, &path);
102 btrfs_release_path(root, &path);
103 if (ret != 0)
104 goto error;
105 ptr = radix_tree_delete(radix, key.objectid);
106 if (!ptr)
107 goto error;
108 return 0;
109error:
110 printf("failed to delete %Lu\n", key.objectid);
111 return -1;
112}
113
114static int lookup_item(struct btrfs_trans_handle *trans, struct btrfs_root
115 *root, struct radix_tree_root *radix)
116{
117 struct btrfs_path path;
118 struct btrfs_key key;
119 int ret;
120 btrfs_init_path(&path);
121 ret = setup_key(radix, &key, 1);
122 if (ret < 0)
123 return 0;
124 ret = btrfs_search_slot(trans, root, &key, &path, 0, 1);
125 btrfs_release_path(root, &path);
126 if (ret)
127 goto error;
128 return 0;
129error:
130 printf("unable to find key %Lu\n", key.objectid);
131 return -1;
132}
133
134static int lookup_enoent(struct btrfs_trans_handle *trans, struct btrfs_root
135 *root, struct radix_tree_root *radix)
136{
137 struct btrfs_path path;
138 struct btrfs_key key;
139 int ret;
140 btrfs_init_path(&path);
141 ret = setup_key(radix, &key, 0);
142 if (ret < 0)
143 return ret;
144 ret = btrfs_search_slot(trans, root, &key, &path, 0, 0);
145 btrfs_release_path(root, &path);
146 if (ret <= 0)
147 goto error;
148 return 0;
149error:
150 printf("able to find key that should not exist %Lu\n", key.objectid);
151 return -1;
152}
153
154static int empty_tree(struct btrfs_trans_handle *trans, struct btrfs_root
155 *root, struct radix_tree_root *radix, int nr)
156{
157 struct btrfs_path path;
158 struct btrfs_key key;
159 unsigned long found = 0;
160 int ret;
161 int slot;
162 int *ptr;
163 int count = 0;
164
165 key.offset = 0;
166 key.flags = 0;
167 btrfs_set_key_type(&key, BTRFS_STRING_ITEM_KEY);
168 key.objectid = (unsigned long)-1;
169 while(nr-- >= 0) {
170 btrfs_init_path(&path);
171 ret = btrfs_search_slot(trans, root, &key, &path, -1, 1);
172 if (ret < 0) {
173 btrfs_release_path(root, &path);
174 return ret;
175 }
176 if (ret != 0) {
177 if (path.slots[0] == 0) {
178 btrfs_release_path(root, &path);
179 break;
180 }
181 path.slots[0] -= 1;
182 }
183 slot = path.slots[0];
184 found = btrfs_disk_key_objectid(
185 &path.nodes[0]->leaf.items[slot].key);
186 ret = btrfs_del_item(trans, root, &path);
187 count++;
188 if (ret) {
189 fprintf(stderr,
190 "failed to remove %lu from tree\n",
191 found);
192 return -1;
193 }
194 btrfs_release_path(root, &path);
195 ptr = radix_tree_delete(radix, found);
196 if (!ptr)
197 goto error;
198 if (!keep_running)
199 break;
200 }
201 return 0;
202error:
203 fprintf(stderr, "failed to delete from the radix %lu\n", found);
204 return -1;
205}
206
207static int fill_tree(struct btrfs_trans_handle *trans, struct btrfs_root *root,
208 struct radix_tree_root *radix, int count)
209{
210 int i;
211 int ret = 0;
212 for (i = 0; i < count; i++) {
213 ret = ins_one(trans, root, radix);
214 if (ret) {
215 fprintf(stderr, "fill failed\n");
216 goto out;
217 }
218 if (i % 1000 == 0) {
219 ret = btrfs_commit_transaction(trans, root, &super);
220 if (ret) {
221 fprintf(stderr, "fill commit failed\n");
222 return ret;
223 }
224 }
225 if (i && i % 10000 == 0) {
226 printf("bigfill %d\n", i);
227 }
228 if (!keep_running)
229 break;
230 }
231out:
232 return ret;
233}
234
235static int bulk_op(struct btrfs_trans_handle *trans, struct btrfs_root *root,
236 struct radix_tree_root *radix)
237{
238 int ret;
239 int nr = rand() % 5000;
240 static int run_nr = 0;
241
242 /* do the bulk op much less frequently */
243 if (run_nr++ % 100)
244 return 0;
245 ret = empty_tree(trans, root, radix, nr);
246 if (ret)
247 return ret;
248 ret = fill_tree(trans, root, radix, nr);
249 if (ret)
250 return ret;
251 return 0;
252}
253
254
255int (*ops[])(struct btrfs_trans_handle *,
256 struct btrfs_root *root, struct radix_tree_root *radix) =
257 { ins_one, insert_dup, del_one, lookup_item,
258 lookup_enoent, bulk_op };
259
260static int fill_radix(struct btrfs_root *root, struct radix_tree_root *radix)
261{
262 struct btrfs_path path;
263 struct btrfs_key key;
264 unsigned long found;
265 int ret;
266 int slot;
267 int i;
268
269 key.offset = 0;
270 key.flags = 0;
271 btrfs_set_key_type(&key, BTRFS_STRING_ITEM_KEY);
272 key.objectid = (unsigned long)-1;
273 while(1) {
274 btrfs_init_path(&path);
275 ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
276 if (ret < 0) {
277 btrfs_release_path(root, &path);
278 return ret;
279 }
280 slot = path.slots[0];
281 if (ret != 0) {
282 if (slot == 0) {
283 btrfs_release_path(root, &path);
284 break;
285 }
286 slot -= 1;
287 }
288 for (i = slot; i >= 0; i--) {
289 found = btrfs_disk_key_objectid(&path.nodes[0]->
290 leaf.items[i].key);
291 radix_tree_preload(GFP_KERNEL);
292 ret = radix_tree_insert(radix, found, (void *)found);
293 if (ret) {
294 fprintf(stderr,
295 "failed to insert %lu into radix\n",
296 found);
297 exit(1);
298 }
299
300 radix_tree_preload_end();
301 }
302 btrfs_release_path(root, &path);
303 key.objectid = found - 1;
304 if (key.objectid > found)
305 break;
306 }
307 return 0;
308}
309void sigstopper(int ignored)
310{
311 keep_running = 0;
312 fprintf(stderr, "caught exit signal, stopping\n");
313}
314
315int print_usage(void)
316{
317 printf("usage: tester [-ih] [-c count] [-f count]\n");
318 printf("\t -c count -- iteration count after filling\n");
319 printf("\t -f count -- run this many random inserts before starting\n");
320 printf("\t -i -- only do initial fill\n");
321 printf("\t -h -- this help text\n");
322 exit(1);
323}
324int main(int ac, char **av)
325{
326 RADIX_TREE(radix, GFP_KERNEL);
327 struct btrfs_root *root;
328 int i;
329 int ret;
330 int count;
331 int op;
332 int iterations = 20000;
333 int init_fill_count = 800000;
334 int err = 0;
335 int initial_only = 0;
336 struct btrfs_trans_handle *trans;
337 radix_tree_init();
338 root = open_ctree("dbfile", &super);
339 fill_radix(root, &radix);
340
341 signal(SIGTERM, sigstopper);
342 signal(SIGINT, sigstopper);
343
344 for (i = 1 ; i < ac ; i++) {
345 if (strcmp(av[i], "-i") == 0) {
346 initial_only = 1;
347 } else if (strcmp(av[i], "-c") == 0) {
348 iterations = atoi(av[i+1]);
349 i++;
350 } else if (strcmp(av[i], "-f") == 0) {
351 init_fill_count = atoi(av[i+1]);
352 i++;
353 } else {
354 print_usage();
355 }
356 }
357 printf("initial fill\n");
358 trans = btrfs_start_transaction(root, 1);
359 ret = fill_tree(trans, root, &radix, init_fill_count);
360 printf("starting run\n");
361 if (ret) {
362 err = ret;
363 goto out;
364 }
365 if (initial_only == 1) {
366 goto out;
367 }
368 for (i = 0; i < iterations; i++) {
369 op = rand() % ARRAY_SIZE(ops);
370 count = rand() % 128;
371 if (i % 2000 == 0) {
372 printf("%d\n", i);
373 fflush(stdout);
374 }
375 if (i && i % 5000 == 0) {
376 printf("open & close, root level %d nritems %d\n",
377 btrfs_header_level(&root->node->node.header),
378 btrfs_header_nritems(&root->node->node.header));
379 close_ctree(root, &super);
380 root = open_ctree("dbfile", &super);
381 }
382 while(count--) {
383 ret = ops[op](trans, root, &radix);
384 if (ret) {
385 fprintf(stderr, "op %d failed %d:%d\n",
386 op, i, iterations);
387 btrfs_print_tree(root, root->node);
388 fprintf(stderr, "op %d failed %d:%d\n",
389 op, i, iterations);
390 err = ret;
391 goto out;
392 }
393 if (ops[op] == bulk_op)
394 break;
395 if (keep_running == 0) {
396 err = 0;
397 goto out;
398 }
399 }
400 }
401out:
402 close_ctree(root, &super);
403 return err;
404}
405