aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/Makefile5
-rw-r--r--fs/btrfs/ctree.h72
-rw-r--r--fs/btrfs/dir-item.c58
-rw-r--r--fs/btrfs/dir-test.c404
-rw-r--r--fs/btrfs/print-tree.c12
5 files changed, 477 insertions, 74 deletions
diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile
index ee78cdd08c04..ea3e1493baa9 100644
--- a/fs/btrfs/Makefile
+++ b/fs/btrfs/Makefile
@@ -1,4 +1,3 @@
1
2CC=gcc 1CC=gcc
3CFLAGS = -g -Wall 2CFLAGS = -g -Wall
4headers = radix-tree.h ctree.h disk-io.h kerncompat.h print-tree.h list.h 3headers = radix-tree.h ctree.h disk-io.h kerncompat.h print-tree.h list.h
@@ -15,7 +14,7 @@ check=sparse $(CHECKFLAGS)
15 $(check) $< 14 $(check) $<
16 $(CC) $(CFLAGS) -c $< 15 $(CC) $(CFLAGS) -c $<
17 16
18all: tester debug-tree quick-test 17all: tester debug-tree quick-test dir-test
19 18
20debug-tree: $(objects) debug-tree.o 19debug-tree: $(objects) debug-tree.o
21 gcc $(CFLAGS) -o debug-tree $(objects) debug-tree.o 20 gcc $(CFLAGS) -o debug-tree $(objects) debug-tree.o
@@ -23,6 +22,8 @@ debug-tree: $(objects) debug-tree.o
23tester: $(objects) random-test.o 22tester: $(objects) random-test.o
24 gcc $(CFLAGS) -o tester $(objects) random-test.o 23 gcc $(CFLAGS) -o tester $(objects) random-test.o
25 24
25dir-test: $(objects) dir-test.o
26 gcc $(CFLAGS) -o dir-test $(objects) dir-test.o
26quick-test: $(objects) quick-test.o 27quick-test: $(objects) quick-test.o
27 gcc $(CFLAGS) -o quick-test $(objects) quick-test.o 28 gcc $(CFLAGS) -o quick-test $(objects) quick-test.o
28 29
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index e8a26fd8ea9f..7a3492d5888e 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -180,37 +180,6 @@ struct btrfs_root {
180#define BTRFS_EXTENT_ITEM_KEY 4 180#define BTRFS_EXTENT_ITEM_KEY 4
181#define BTRFS_STRING_ITEM_KEY 5 181#define BTRFS_STRING_ITEM_KEY 5
182 182
183static inline u64 btrfs_dir_objectid(struct btrfs_dir_item *d)
184{
185 return le64_to_cpu(d->objectid);
186}
187
188static inline void btrfs_set_dir_objectid(struct btrfs_dir_item *d, u64 val)
189{
190 d->objectid = cpu_to_le64(val);
191}
192
193static inline u16 btrfs_dir_flags(struct btrfs_dir_item *d)
194{
195 return le16_to_cpu(d->flags);
196}
197
198static inline void btrfs_set_dir_flags(struct btrfs_dir_item *d, u16 val)
199{
200 d->flags = cpu_to_le16(val);
201}
202
203static inline u8 btrfs_dir_type(struct btrfs_dir_item *d)
204{
205 return d->type;
206}
207
208static inline void btrfs_set_dir_type(struct btrfs_dir_item *d, u8 val)
209{
210 d->type = val;
211}
212
213
214static inline u64 btrfs_extent_owner(struct btrfs_extent_item *ei) 183static inline u64 btrfs_extent_owner(struct btrfs_extent_item *ei)
215{ 184{
216 return le64_to_cpu(ei->owner); 185 return le64_to_cpu(ei->owner);
@@ -267,6 +236,41 @@ static inline void btrfs_set_item_size(struct btrfs_item *item, u16 val)
267 item->size = cpu_to_le16(val); 236 item->size = cpu_to_le16(val);
268} 237}
269 238
239static inline u64 btrfs_dir_objectid(struct btrfs_dir_item *d)
240{
241 return le64_to_cpu(d->objectid);
242}
243
244static inline void btrfs_set_dir_objectid(struct btrfs_dir_item *d, u64 val)
245{
246 d->objectid = cpu_to_le64(val);
247}
248
249static inline u16 btrfs_dir_flags(struct btrfs_dir_item *d)
250{
251 return le16_to_cpu(d->flags);
252}
253
254static inline void btrfs_set_dir_flags(struct btrfs_dir_item *d, u16 val)
255{
256 d->flags = cpu_to_le16(val);
257}
258
259static inline u8 btrfs_dir_type(struct btrfs_dir_item *d)
260{
261 return d->type;
262}
263
264static inline void btrfs_set_dir_type(struct btrfs_dir_item *d, u8 val)
265{
266 d->type = val;
267}
268
269static inline u32 btrfs_dir_name_len(struct btrfs_item *i)
270{
271 return btrfs_item_size(i) - sizeof(struct btrfs_dir_item);
272}
273
270static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu, 274static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu,
271 struct btrfs_disk_key *disk) 275 struct btrfs_disk_key *disk)
272{ 276{
@@ -506,4 +510,10 @@ int btrfs_update_root(struct btrfs_root *root, struct btrfs_key *key,
506 struct btrfs_root_item *item); 510 struct btrfs_root_item *item);
507int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, 511int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
508 struct btrfs_root_item *item, struct btrfs_key *key); 512 struct btrfs_root_item *item, struct btrfs_key *key);
513int btrfs_insert_dir_item(struct btrfs_root *root, char *name, int name_len,
514 u64 dir, u64 objectid, u8 type);
515int btrfs_lookup_dir_item(struct btrfs_root *root, struct btrfs_path *path,
516 u64 dir, char *name, int name_len, int mod);
517int btrfs_match_dir_item_name(struct btrfs_root *root, struct btrfs_path *path,
518 char *name, int name_len);
509#endif 519#endif
diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c
index 2a888e97e1a2..8043b2ef10d1 100644
--- a/fs/btrfs/dir-item.c
+++ b/fs/btrfs/dir-item.c
@@ -18,6 +18,7 @@ int btrfs_insert_dir_item(struct btrfs_root *root, char *name, int name_len,
18 18
19 key.objectid = dir; 19 key.objectid = dir;
20 key.flags = 0; 20 key.flags = 0;
21 btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
21 ret = btrfs_name_hash(name, name_len, &key.offset); 22 ret = btrfs_name_hash(name, name_len, &key.offset);
22 BUG_ON(ret); 23 BUG_ON(ret);
23 btrfs_init_path(&path); 24 btrfs_init_path(&path);
@@ -38,65 +39,40 @@ out:
38 return ret; 39 return ret;
39} 40}
40 41
41int btrfs_del_dir_item(struct btrfs_root *root, u64 dir, char *name, 42int btrfs_lookup_dir_item(struct btrfs_root *root, struct btrfs_path *path,
42 int name_len) 43 u64 dir, char *name, int name_len, int mod)
43{ 44{
44 int ret = 0; 45 int ret;
45 struct btrfs_path path;
46 struct btrfs_key key; 46 struct btrfs_key key;
47 int ins_len = mod < 0 ? -1 : 0;
48 int cow = mod != 0;
47 49
48 key.objectid = dir; 50 key.objectid = dir;
49 key.flags = 0; 51 key.flags = 0;
52 btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
50 ret = btrfs_name_hash(name, name_len, &key.offset); 53 ret = btrfs_name_hash(name, name_len, &key.offset);
51 BUG_ON(ret); 54 BUG_ON(ret);
52 btrfs_init_path(&path); 55 ret = btrfs_search_slot(root, &key, path, ins_len, cow);
53 ret = btrfs_search_slot(root, &key, &path, 0, 1);
54 if (ret)
55 goto out;
56 ret = btrfs_del_item(root, &path);
57out:
58 btrfs_release_path(root, &path);
59 return ret; 56 return ret;
60} 57}
61 58
62int btrfs_lookup_dir_item(struct btrfs_root *root, u64 dir, char *name, 59int btrfs_match_dir_item_name(struct btrfs_root *root, struct btrfs_path *path,
63 int name_len, u64 *objectid) 60 char *name, int name_len)
64{ 61{
65 int ret = 0; 62 struct btrfs_item *item;
66 struct btrfs_path path;
67 struct btrfs_dir_item *dir_item; 63 struct btrfs_dir_item *dir_item;
68 char *name_ptr; 64 char *name_ptr;
69 struct btrfs_key key;
70 u32 item_len; 65 u32 item_len;
71 struct btrfs_item *item; 66 item = path->nodes[0]->leaf.items + path->slots[0];
72
73 key.objectid = dir;
74 key.flags = 0;
75 ret = btrfs_name_hash(name, name_len, &key.offset);
76 BUG_ON(ret);
77 btrfs_init_path(&path);
78 ret = btrfs_search_slot(root, &key, &path, 0, 0);
79 if (ret)
80 goto out;
81
82 dir_item = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0],
83 struct btrfs_dir_item);
84
85 item = path.nodes[0]->leaf.items + path.slots[0];
86 item_len = btrfs_item_size(item); 67 item_len = btrfs_item_size(item);
87 if (item_len != name_len + sizeof(struct btrfs_dir_item)) { 68 if (item_len != name_len + sizeof(struct btrfs_dir_item)) {
88 BUG(); 69 return 0;
89 ret = 1;
90 goto out;
91 } 70 }
71 dir_item = btrfs_item_ptr(&path->nodes[0]->leaf, path->slots[0],
72 struct btrfs_dir_item);
92 name_ptr = (char *)(dir_item + 1); 73 name_ptr = (char *)(dir_item + 1);
93 if (memcmp(name_ptr, name, name_len)) { 74 if (memcmp(name_ptr, name, name_len)) {
94 BUG(); 75 return 0;
95 ret = 1;
96 goto out;
97 } 76 }
98 *objectid = btrfs_dir_objectid(dir_item); 77 return 1;
99out:
100 btrfs_release_path(root, &path);
101 return ret;
102} 78}
diff --git a/fs/btrfs/dir-test.c b/fs/btrfs/dir-test.c
new file mode 100644
index 000000000000..b482b8f49f8a
--- /dev/null
+++ b/fs/btrfs/dir-test.c
@@ -0,0 +1,404 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <signal.h>
4#include <unistd.h>
5#include "kerncompat.h"
6#include "radix-tree.h"
7#include "ctree.h"
8#include "disk-io.h"
9#include "print-tree.h"
10#include "hash.h"
11
12int keep_running = 1;
13struct btrfs_super_block super;
14static u64 dir_oid = 44556;
15static u64 file_oid = 33778;
16
17static int find_num(struct radix_tree_root *root, unsigned long *num_ret,
18 int exists)
19{
20 unsigned long num = rand();
21 unsigned long res[2];
22 int ret;
23
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 *num_ret = num;
38 return 0;
39}
40
41static int ins_one(struct btrfs_root *root, struct radix_tree_root *radix)
42{
43 int ret;
44 char buf[128];
45 unsigned long oid;
46 struct btrfs_path path;
47
48 find_num(radix, &oid, 0);
49 sprintf(buf, "str-%lu", oid);
50
51 ret = btrfs_insert_dir_item(root, buf, strlen(buf), dir_oid, file_oid,
52 1);
53 if (ret)
54 goto error;
55
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 if (ret != -EEXIST)
64 goto fatal;
65
66 /*
67 * if we got an EEXIST, it may be due to hash collision, double
68 * check
69 */
70 btrfs_init_path(&path);
71 ret = btrfs_lookup_dir_item(root, &path, dir_oid, buf, strlen(buf), 0);
72 if (ret)
73 goto fatal_release;
74 if (!btrfs_match_dir_item_name(root, &path, buf, strlen(buf))) {
75 struct btrfs_dir_item *di;
76 char *found;
77 u32 found_len;
78 u64 myhash;
79 u64 foundhash;
80
81 di = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0],
82 struct btrfs_dir_item);
83 found = (char *)(di + 1);
84 found_len = btrfs_dir_name_len(path.nodes[0]->leaf.items +
85 path.slots[0]);
86 btrfs_name_hash(buf, strlen(buf), &myhash);
87 btrfs_name_hash(found, found_len, &foundhash);
88 if (myhash != foundhash)
89 goto fatal_release;
90 btrfs_release_path(root, &path);
91 return 0;
92 }
93fatal_release:
94 btrfs_release_path(root, &path);
95fatal:
96 printf("failed to insert %lu ret %d\n", oid, ret);
97 return -1;
98}
99
100static int insert_dup(struct btrfs_root *root, struct radix_tree_root *radix)
101{
102 int ret;
103 char buf[128];
104 unsigned long oid;
105
106 ret = find_num(radix, &oid, 1);
107 if (ret < 0)
108 return 0;
109 sprintf(buf, "str-%lu", oid);
110
111 ret = btrfs_insert_dir_item(root, buf, strlen(buf), dir_oid, file_oid,
112 1);
113 if (ret != -EEXIST) {
114 printf("insert on %s gave us %d\n", buf, ret);
115 return 1;
116 }
117 return 0;
118}
119
120static int del_one(struct btrfs_root *root, struct radix_tree_root *radix)
121{
122 int ret;
123 char buf[128];
124 unsigned long oid;
125 struct btrfs_path path;
126 unsigned long *ptr;
127
128 ret = find_num(radix, &oid, 1);
129 if (ret < 0)
130 return 0;
131 sprintf(buf, "str-%lu", oid);
132 btrfs_init_path(&path);
133 ret = btrfs_lookup_dir_item(root, &path, dir_oid, buf, strlen(buf), -1);
134 if (ret)
135 goto out_release;
136 ret = btrfs_del_item(root, &path);
137 if (ret)
138 goto out_release;
139 btrfs_release_path(root, &path);
140 ptr = radix_tree_delete(radix, oid);
141 if (!ptr) {
142 ret = -5555;
143 goto out;
144 }
145 return 0;
146out_release:
147 btrfs_release_path(root, &path);
148out:
149 printf("failed to delete %lu %d\n", oid, ret);
150 return -1;
151}
152
153static int lookup_item(struct btrfs_root *root, struct radix_tree_root *radix)
154{
155 struct btrfs_path path;
156 char buf[128];
157 int ret;
158 unsigned long oid;
159
160 ret = find_num(radix, &oid, 1);
161 if (ret < 0)
162 return 0;
163 sprintf(buf, "str-%lu", oid);
164 btrfs_init_path(&path);
165 ret = btrfs_lookup_dir_item(root, &path, dir_oid, buf, strlen(buf), 0);
166 btrfs_release_path(root, &path);
167 if (ret) {
168 printf("unable to find key %lu\n", oid);
169 return -1;
170 }
171 return 0;
172}
173
174static int lookup_enoent(struct btrfs_root *root, struct radix_tree_root *radix)
175{
176 struct btrfs_path path;
177 char buf[128];
178 int ret;
179 unsigned long oid;
180
181 ret = find_num(radix, &oid, 0);
182 if (ret < 0)
183 return 0;
184 sprintf(buf, "str-%lu", oid);
185 btrfs_init_path(&path);
186 ret = btrfs_lookup_dir_item(root, &path, dir_oid, buf, strlen(buf), 0);
187 btrfs_release_path(root, &path);
188 if (!ret) {
189 printf("able to find key that should not exist %lu\n", oid);
190 return -1;
191 }
192 return 0;
193}
194
195static int empty_tree(struct btrfs_root *root, struct radix_tree_root *radix,
196 int nr)
197{
198 struct btrfs_path path;
199 struct btrfs_key key;
200 unsigned long found = 0;
201 u32 found_len;
202 int ret;
203 int slot;
204 int *ptr;
205 int count = 0;
206 char buf[128];
207 struct btrfs_dir_item *di;
208
209 key.offset = (u64)-1;
210 key.flags = 0;
211 btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
212 key.objectid = dir_oid;
213 while(nr-- >= 0) {
214 btrfs_init_path(&path);
215 ret = btrfs_search_slot(root, &key, &path, -1, 1);
216 if (ret < 0) {
217 btrfs_release_path(root, &path);
218 return ret;
219 }
220 if (ret != 0) {
221 if (path.slots[0] == 0) {
222 btrfs_release_path(root, &path);
223 break;
224 }
225 path.slots[0] -= 1;
226 }
227 slot = path.slots[0];
228 di = btrfs_item_ptr(&path.nodes[0]->leaf, slot,
229 struct btrfs_dir_item);
230 found_len = btrfs_dir_name_len(path.nodes[0]->leaf.items +
231 slot);
232 memcpy(buf, (char *)(di + 1), found_len);
233 BUG_ON(found_len > 128);
234 buf[found_len] = '\0';
235 found = atoi(buf + 4);
236 ret = btrfs_del_item(root, &path);
237 count++;
238 if (ret) {
239 fprintf(stderr,
240 "failed to remove %lu from tree\n",
241 found);
242 return -1;
243 }
244 btrfs_release_path(root, &path);
245 ptr = radix_tree_delete(radix, found);
246 if (!ptr)
247 goto error;
248 if (!keep_running)
249 break;
250 }
251 return 0;
252error:
253 fprintf(stderr, "failed to delete from the radix %lu\n", found);
254 return -1;
255}
256
257static int fill_tree(struct btrfs_root *root, struct radix_tree_root *radix,
258 int count)
259{
260 int i;
261 int ret = 0;
262 for (i = 0; i < count; i++) {
263 ret = ins_one(root, radix);
264 if (ret) {
265 fprintf(stderr, "fill failed\n");
266 goto out;
267 }
268 if (i % 1000 == 0) {
269 ret = btrfs_commit_transaction(root, &super);
270 if (ret) {
271 fprintf(stderr, "fill commit failed\n");
272 return ret;
273 }
274 }
275 if (i && i % 10000 == 0) {
276 printf("bigfill %d\n", i);
277 }
278 if (!keep_running)
279 break;
280 }
281out:
282 return ret;
283}
284
285static int bulk_op(struct btrfs_root *root, struct radix_tree_root *radix)
286{
287 int ret;
288 int nr = rand() % 5000;
289 static int run_nr = 0;
290
291 /* do the bulk op much less frequently */
292 if (run_nr++ % 100)
293 return 0;
294 ret = empty_tree(root, radix, nr);
295 if (ret)
296 return ret;
297 ret = fill_tree(root, radix, nr);
298 if (ret)
299 return ret;
300 return 0;
301}
302
303
304int (*ops[])(struct btrfs_root *root, struct radix_tree_root *radix) =
305 { ins_one, insert_dup, del_one, lookup_item,
306 lookup_enoent, bulk_op };
307
308void sigstopper(int ignored)
309{
310 keep_running = 0;
311 fprintf(stderr, "caught exit signal, stopping\n");
312}
313
314int print_usage(void)
315{
316 printf("usage: tester [-ih] [-c count] [-f count]\n");
317 printf("\t -c count -- iteration count after filling\n");
318 printf("\t -f count -- run this many random inserts before starting\n");
319 printf("\t -i -- only do initial fill\n");
320 printf("\t -h -- this help text\n");
321 exit(1);
322}
323int main(int ac, char **av)
324{
325 RADIX_TREE(radix, GFP_KERNEL);
326 struct btrfs_root *root;
327 int i;
328 int ret;
329 int count;
330 int op;
331 int iterations = 20000;
332 int init_fill_count = 800000;
333 int err = 0;
334 int initial_only = 0;
335 radix_tree_init();
336
337 printf("removing old tree\n");
338 unlink("dbfile");
339 root = open_ctree("dbfile", &super);
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 ret = fill_tree(root, &radix, init_fill_count);
359 printf("starting run\n");
360 if (ret) {
361 err = ret;
362 goto out;
363 }
364 if (initial_only == 1) {
365 goto out;
366 }
367 for (i = 0; i < iterations; i++) {
368 op = rand() % ARRAY_SIZE(ops);
369 count = rand() % 128;
370 if (i % 2000 == 0) {
371 printf("%d\n", i);
372 fflush(stdout);
373 }
374 if (i && i % 5000 == 0) {
375 printf("open & close, root level %d nritems %d\n",
376 btrfs_header_level(&root->node->node.header),
377 btrfs_header_nritems(&root->node->node.header));
378 close_ctree(root, &super);
379 root = open_ctree("dbfile", &super);
380 }
381 while(count--) {
382 ret = ops[op](root, &radix);
383 if (ret) {
384 fprintf(stderr, "op %d failed %d:%d\n",
385 op, i, iterations);
386 btrfs_print_tree(root, root->node);
387 fprintf(stderr, "op %d failed %d:%d\n",
388 op, i, iterations);
389 err = ret;
390 goto out;
391 }
392 if (ops[op] == bulk_op)
393 break;
394 if (keep_running == 0) {
395 err = 0;
396 goto out;
397 }
398 }
399 }
400out:
401 close_ctree(root, &super);
402 return err;
403}
404
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index f2745b247473..ad244d658117 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -12,7 +12,10 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
12 struct btrfs_item *item; 12 struct btrfs_item *item;
13 struct btrfs_extent_item *ei; 13 struct btrfs_extent_item *ei;
14 struct btrfs_root_item *ri; 14 struct btrfs_root_item *ri;
15 struct btrfs_dir_item *di;
15 u32 type; 16 u32 type;
17 u32 namelen;
18
16 printf("leaf %Lu total ptrs %d free space %d\n", 19 printf("leaf %Lu total ptrs %d free space %d\n",
17 btrfs_header_blocknr(&l->header), nr, 20 btrfs_header_blocknr(&l->header), nr,
18 btrfs_leaf_free_space(root, l)); 21 btrfs_leaf_free_space(root, l));
@@ -31,6 +34,15 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
31 case BTRFS_INODE_ITEM_KEY: 34 case BTRFS_INODE_ITEM_KEY:
32 break; 35 break;
33 case BTRFS_DIR_ITEM_KEY: 36 case BTRFS_DIR_ITEM_KEY:
37 namelen = btrfs_item_size(l->items + i) - sizeof(*di);
38 di = btrfs_item_ptr(l, i, struct btrfs_dir_item);
39 printf("\t\tdir oid %Lu flags %u type %u\n",
40 btrfs_dir_objectid(di),
41 btrfs_dir_flags(di),
42 btrfs_dir_type(di));
43 printf("\t\tname %.*s\n",
44 namelen, (char *)(di + 1));
45
34 break; 46 break;
35 case BTRFS_ROOT_ITEM_KEY: 47 case BTRFS_ROOT_ITEM_KEY:
36 ri = btrfs_item_ptr(l, i, struct btrfs_root_item); 48 ri = btrfs_item_ptr(l, i, struct btrfs_root_item);