4 #include "kerncompat.h"
5 #include "radix-tree.h"
8 #include "print-tree.h"
11 struct btrfs_super_block super;
13 static int setup_key(struct radix_tree_root *root, struct btrfs_key *key,
21 btrfs_set_key_type(key, BTRFS_STRING_ITEM_KEY);
24 ret = radix_tree_gang_lookup(root, (void **)res, num, 2);
29 } else if (ret != 0 && num == res[0]) {
31 if (ret > 1 && num == res[1]) {
40 static int ins_one(struct btrfs_root *root, struct radix_tree_root *radix)
42 struct btrfs_path path;
47 btrfs_init_path(&path);
48 ret = setup_key(radix, &key, 0);
49 sprintf(buf, "str-%Lu\n", key.objectid);
50 ret = btrfs_insert_item(root, &key, buf, strlen(buf));
53 oid = (unsigned long)key.objectid;
54 radix_tree_preload(GFP_KERNEL);
55 ret = radix_tree_insert(radix, oid, (void *)oid);
56 radix_tree_preload_end();
61 printf("failed to insert %Lu\n", key.objectid);
65 static int insert_dup(struct btrfs_root *root, struct radix_tree_root *radix)
67 struct btrfs_path path;
71 btrfs_init_path(&path);
72 ret = setup_key(radix, &key, 1);
75 sprintf(buf, "str-%Lu\n", key.objectid);
76 ret = btrfs_insert_item(root, &key, buf, strlen(buf));
78 printf("insert on %Lu gave us %d\n", key.objectid, ret);
84 static int del_one(struct btrfs_root *root, struct radix_tree_root *radix)
86 struct btrfs_path path;
90 btrfs_init_path(&path);
91 ret = setup_key(radix, &key, 1);
94 ret = btrfs_search_slot(root, &key, &path, -1, 1);
97 ret = btrfs_del_item(root, &path);
98 btrfs_release_path(root, &path);
101 ptr = radix_tree_delete(radix, key.objectid);
106 printf("failed to delete %Lu\n", key.objectid);
110 static int lookup_item(struct btrfs_root *root, struct radix_tree_root *radix)
112 struct btrfs_path path;
113 struct btrfs_key key;
115 btrfs_init_path(&path);
116 ret = setup_key(radix, &key, 1);
119 ret = btrfs_search_slot(root, &key, &path, 0, 1);
120 btrfs_release_path(root, &path);
125 printf("unable to find key %Lu\n", key.objectid);
129 static int lookup_enoent(struct btrfs_root *root, struct radix_tree_root *radix)
131 struct btrfs_path path;
132 struct btrfs_key key;
134 btrfs_init_path(&path);
135 ret = setup_key(radix, &key, 0);
138 ret = btrfs_search_slot(root, &key, &path, 0, 0);
139 btrfs_release_path(root, &path);
144 printf("able to find key that should not exist %Lu\n", key.objectid);
148 static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix,
151 struct btrfs_path path;
152 struct btrfs_key key;
153 unsigned long found = 0;
161 btrfs_set_key_type(&key, BTRFS_STRING_ITEM_KEY);
162 key.objectid = (unsigned long)-1;
164 btrfs_init_path(&path);
165 ret = btrfs_search_slot(root, &key, &path, -1, 1);
167 btrfs_release_path(root, &path);
171 if (path.slots[0] == 0) {
172 btrfs_release_path(root, &path);
177 slot = path.slots[0];
178 found = btrfs_disk_key_objectid(
179 &path.nodes[0]->leaf.items[slot].key);
180 ret = btrfs_del_item(root, &path);
184 "failed to remove %lu from tree\n",
188 btrfs_release_path(root, &path);
189 ptr = radix_tree_delete(radix, found);
197 fprintf(stderr, "failed to delete from the radix %lu\n", found);
201 static int fill_tree(struct btrfs_root *root, struct radix_tree_root *radix,
206 for (i = 0; i < count; i++) {
207 ret = ins_one(root, radix);
209 fprintf(stderr, "fill failed\n");
213 ret = btrfs_commit_transaction(root, &super);
215 fprintf(stderr, "fill commit failed\n");
219 if (i && i % 10000 == 0) {
220 printf("bigfill %d\n", i);
229 static int bulk_op(struct btrfs_root *root, struct radix_tree_root *radix)
232 int nr = rand() % 5000;
233 static int run_nr = 0;
235 /* do the bulk op much less frequently */
238 ret = empty_tree(root, radix, nr);
241 ret = fill_tree(root, radix, nr);
248 int (*ops[])(struct btrfs_root *root, struct radix_tree_root *radix) =
249 { ins_one, insert_dup, del_one, lookup_item,
250 lookup_enoent, bulk_op };
252 static int fill_radix(struct btrfs_root *root, struct radix_tree_root *radix)
254 struct btrfs_path path;
255 struct btrfs_key key;
263 btrfs_set_key_type(&key, BTRFS_STRING_ITEM_KEY);
264 key.objectid = (unsigned long)-1;
266 btrfs_init_path(&path);
267 ret = btrfs_search_slot(root, &key, &path, 0, 0);
269 btrfs_release_path(root, &path);
272 slot = path.slots[0];
275 btrfs_release_path(root, &path);
280 for (i = slot; i >= 0; i--) {
281 found = btrfs_disk_key_objectid(&path.nodes[0]->
283 radix_tree_preload(GFP_KERNEL);
284 ret = radix_tree_insert(radix, found, (void *)found);
287 "failed to insert %lu into radix\n",
292 radix_tree_preload_end();
294 btrfs_release_path(root, &path);
295 key.objectid = found - 1;
296 if (key.objectid > found)
301 void sigstopper(int ignored)
304 fprintf(stderr, "caught exit signal, stopping\n");
307 int print_usage(void)
309 printf("usage: tester [-ih] [-c count] [-f count]\n");
310 printf("\t -c count -- iteration count after filling\n");
311 printf("\t -f count -- run this many random inserts before starting\n");
312 printf("\t -i -- only do initial fill\n");
313 printf("\t -h -- this help text\n");
316 int main(int ac, char **av)
318 RADIX_TREE(radix, GFP_KERNEL);
319 struct btrfs_root *root;
324 int iterations = 20000;
325 int init_fill_count = 800000;
327 int initial_only = 0;
329 root = open_ctree("dbfile", &super);
330 fill_radix(root, &radix);
332 signal(SIGTERM, sigstopper);
333 signal(SIGINT, sigstopper);
335 for (i = 1 ; i < ac ; i++) {
336 if (strcmp(av[i], "-i") == 0) {
338 } else if (strcmp(av[i], "-c") == 0) {
339 iterations = atoi(av[i+1]);
341 } else if (strcmp(av[i], "-f") == 0) {
342 init_fill_count = atoi(av[i+1]);
348 printf("initial fill\n");
349 ret = fill_tree(root, &radix, init_fill_count);
350 printf("starting run\n");
355 if (initial_only == 1) {
358 for (i = 0; i < iterations; i++) {
359 op = rand() % ARRAY_SIZE(ops);
360 count = rand() % 128;
365 if (i && i % 5000 == 0) {
366 printf("open & close, root level %d nritems %d\n",
367 btrfs_header_level(&root->node->node.header),
368 btrfs_header_nritems(&root->node->node.header));
369 close_ctree(root, &super);
370 root = open_ctree("dbfile", &super);
373 ret = ops[op](root, &radix);
375 fprintf(stderr, "op %d failed %d:%d\n",
377 btrfs_print_tree(root, root->node);
378 fprintf(stderr, "op %d failed %d:%d\n",
383 if (ops[op] == bulk_op)
385 if (keep_running == 0) {
392 close_ctree(root, &super);