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
,
23 ret
= radix_tree_gang_lookup(root
, (void **)res
, num
, 2);
28 } else if (ret
!= 0 && num
== res
[0]) {
30 if (ret
> 1 && num
== res
[1]) {
39 static int ins_one(struct btrfs_root
*root
, struct radix_tree_root
*radix
)
41 struct btrfs_path path
;
46 btrfs_init_path(&path
);
47 ret
= setup_key(radix
, &key
, 0);
48 sprintf(buf
, "str-%Lu\n", key
.objectid
);
49 ret
= btrfs_insert_item(root
, &key
, buf
, strlen(buf
));
52 oid
= (unsigned long)key
.objectid
;
53 radix_tree_preload(GFP_KERNEL
);
54 ret
= radix_tree_insert(radix
, oid
, (void *)oid
);
55 radix_tree_preload_end();
60 printf("failed to insert %Lu\n", key
.objectid
);
64 static int insert_dup(struct btrfs_root
*root
, struct radix_tree_root
*radix
)
66 struct btrfs_path path
;
70 btrfs_init_path(&path
);
71 ret
= setup_key(radix
, &key
, 1);
74 sprintf(buf
, "str-%Lu\n", key
.objectid
);
75 ret
= btrfs_insert_item(root
, &key
, buf
, strlen(buf
));
77 printf("insert on %Lu gave us %d\n", key
.objectid
, ret
);
83 static int del_one(struct btrfs_root
*root
, struct radix_tree_root
*radix
)
85 struct btrfs_path path
;
89 btrfs_init_path(&path
);
90 ret
= setup_key(radix
, &key
, 1);
93 ret
= btrfs_search_slot(root
, &key
, &path
, -1, 1);
96 ret
= btrfs_del_item(root
, &path
);
97 btrfs_release_path(root
, &path
);
100 ptr
= radix_tree_delete(radix
, key
.objectid
);
105 printf("failed to delete %Lu\n", key
.objectid
);
109 static int lookup_item(struct btrfs_root
*root
, struct radix_tree_root
*radix
)
111 struct btrfs_path path
;
112 struct btrfs_key key
;
114 btrfs_init_path(&path
);
115 ret
= setup_key(radix
, &key
, 1);
118 ret
= btrfs_search_slot(root
, &key
, &path
, 0, 1);
119 btrfs_release_path(root
, &path
);
124 printf("unable to find key %Lu\n", key
.objectid
);
128 static int lookup_enoent(struct btrfs_root
*root
, struct radix_tree_root
*radix
)
130 struct btrfs_path path
;
131 struct btrfs_key key
;
133 btrfs_init_path(&path
);
134 ret
= setup_key(radix
, &key
, 0);
137 ret
= btrfs_search_slot(root
, &key
, &path
, 0, 0);
138 btrfs_release_path(root
, &path
);
143 printf("able to find key that should not exist %Lu\n", key
.objectid
);
147 static int empty_tree(struct btrfs_root
*root
, struct radix_tree_root
*radix
,
150 struct btrfs_path path
;
151 struct btrfs_key key
;
152 unsigned long found
= 0;
160 key
.objectid
= (unsigned long)-1;
162 btrfs_init_path(&path
);
163 ret
= btrfs_search_slot(root
, &key
, &path
, -1, 1);
165 btrfs_release_path(root
, &path
);
169 if (path
.slots
[0] == 0) {
170 btrfs_release_path(root
, &path
);
175 slot
= path
.slots
[0];
176 found
=btrfs_key_objectid(&path
.nodes
[0]->leaf
.items
[slot
].key
);
177 ret
= btrfs_del_item(root
, &path
);
181 "failed to remove %lu from tree\n",
185 btrfs_release_path(root
, &path
);
186 ptr
= radix_tree_delete(radix
, found
);
194 fprintf(stderr
, "failed to delete from the radix %lu\n", found
);
198 static int fill_tree(struct btrfs_root
*root
, struct radix_tree_root
*radix
,
203 for (i
= 0; i
< count
; i
++) {
204 ret
= ins_one(root
, radix
);
206 fprintf(stderr
, "fill failed\n");
210 ret
= btrfs_commit_transaction(root
, &super
);
212 fprintf(stderr
, "fill commit failed\n");
216 if (i
&& i
% 10000 == 0) {
217 printf("bigfill %d\n", i
);
226 static int bulk_op(struct btrfs_root
*root
, struct radix_tree_root
*radix
)
229 int nr
= rand() % 5000;
230 static int run_nr
= 0;
232 /* do the bulk op much less frequently */
235 ret
= empty_tree(root
, radix
, nr
);
238 ret
= fill_tree(root
, radix
, nr
);
245 int (*ops
[])(struct btrfs_root
*root
, struct radix_tree_root
*radix
) =
246 { ins_one
, insert_dup
, del_one
, lookup_item
,
247 lookup_enoent
, bulk_op
};
249 static int fill_radix(struct btrfs_root
*root
, struct radix_tree_root
*radix
)
251 struct btrfs_path path
;
252 struct btrfs_key key
;
260 key
.objectid
= (unsigned long)-1;
262 btrfs_init_path(&path
);
263 ret
= btrfs_search_slot(root
, &key
, &path
, 0, 0);
265 btrfs_release_path(root
, &path
);
268 slot
= path
.slots
[0];
271 btrfs_release_path(root
, &path
);
276 for (i
= slot
; i
>= 0; i
--) {
277 found
= btrfs_key_objectid(&path
.nodes
[0]->
279 radix_tree_preload(GFP_KERNEL
);
280 ret
= radix_tree_insert(radix
, found
, (void *)found
);
283 "failed to insert %lu into radix\n",
288 radix_tree_preload_end();
290 btrfs_release_path(root
, &path
);
291 key
.objectid
= found
- 1;
292 if (key
.objectid
> found
)
297 void sigstopper(int ignored
)
300 fprintf(stderr
, "caught exit signal, stopping\n");
303 int print_usage(void)
305 printf("usage: tester [-ih] [-c count] [-f count]\n");
306 printf("\t -c count -- iteration count after filling\n");
307 printf("\t -f count -- run this many random inserts before starting\n");
308 printf("\t -i -- only do initial fill\n");
309 printf("\t -h -- this help text\n");
312 int main(int ac
, char **av
)
314 RADIX_TREE(radix
, GFP_KERNEL
);
315 struct btrfs_root
*root
;
320 int iterations
= 20000;
321 int init_fill_count
= 800000;
323 int initial_only
= 0;
325 root
= open_ctree("dbfile", &super
);
326 fill_radix(root
, &radix
);
328 signal(SIGTERM
, sigstopper
);
329 signal(SIGINT
, sigstopper
);
331 for (i
= 1 ; i
< ac
; i
++) {
332 if (strcmp(av
[i
], "-i") == 0) {
334 } else if (strcmp(av
[i
], "-c") == 0) {
335 iterations
= atoi(av
[i
+1]);
337 } else if (strcmp(av
[i
], "-f") == 0) {
338 init_fill_count
= atoi(av
[i
+1]);
344 printf("initial fill\n");
345 ret
= fill_tree(root
, &radix
, init_fill_count
);
346 printf("starting run\n");
351 if (initial_only
== 1) {
354 for (i
= 0; i
< iterations
; i
++) {
355 op
= rand() % ARRAY_SIZE(ops
);
356 count
= rand() % 128;
361 if (i
&& i
% 5000 == 0) {
362 printf("open & close, root level %d nritems %d\n",
363 btrfs_header_level(&root
->node
->node
.header
),
364 btrfs_header_nritems(&root
->node
->node
.header
));
365 close_ctree(root
, &super
);
366 root
= open_ctree("dbfile", &super
);
369 ret
= ops
[op
](root
, &radix
);
371 fprintf(stderr
, "op %d failed %d:%d\n",
373 btrfs_print_tree(root
, root
->node
);
374 fprintf(stderr
, "op %d failed %d:%d\n",
379 if (ops
[op
] == bulk_op
)
381 if (keep_running
== 0) {
388 close_ctree(root
, &super
);