btrfsck: add code to rebuild extent records
[platform/upstream/btrfs-progs.git] / print-tree.c
1 /*
2  * Copyright (C) 2007 Oracle.  All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public
6  * License v2 as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public
14  * License along with this program; if not, write to the
15  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16  * Boston, MA 021110-1307, USA.
17  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <uuid/uuid.h>
22 #include "kerncompat.h"
23 #include "radix-tree.h"
24 #include "ctree.h"
25 #include "disk-io.h"
26 #include "print-tree.h"
27
28 static int print_dir_item(struct extent_buffer *eb, struct btrfs_item *item,
29                           struct btrfs_dir_item *di)
30 {
31         u32 total;
32         u32 cur = 0;
33         u32 len;
34         u32 name_len;
35         u32 data_len;
36         char namebuf[BTRFS_NAME_LEN];
37         struct btrfs_disk_key location;
38
39         total = btrfs_item_size(eb, item);
40         while(cur < total) {
41                 btrfs_dir_item_key(eb, di, &location);
42                 printf("\t\tlocation ");
43                 btrfs_print_key(&location);
44                 printf(" type %u\n", btrfs_dir_type(eb, di));
45                 name_len = btrfs_dir_name_len(eb, di);
46                 data_len = btrfs_dir_data_len(eb, di);
47                 len = (name_len <= sizeof(namebuf))? name_len: sizeof(namebuf);
48                 read_extent_buffer(eb, namebuf, (unsigned long)(di + 1), len);
49                 printf("\t\tnamelen %u datalen %u name: %.*s\n",
50                        name_len, data_len, len, namebuf);
51                 len = sizeof(*di) + name_len + data_len;
52                 di = (struct btrfs_dir_item *)((char *)di + len);
53                 cur += len;
54         }
55         return 0;
56 }
57
58 static int print_inode_ref_item(struct extent_buffer *eb, struct btrfs_item *item,
59                                 struct btrfs_inode_ref *ref)
60 {
61         u32 total;
62         u32 cur = 0;
63         u32 len;
64         u32 name_len;
65         u64 index;
66         char namebuf[BTRFS_NAME_LEN];
67         total = btrfs_item_size(eb, item);
68         while(cur < total) {
69                 name_len = btrfs_inode_ref_name_len(eb, ref);
70                 index = btrfs_inode_ref_index(eb, ref);
71                 len = (name_len <= sizeof(namebuf))? name_len: sizeof(namebuf);
72                 read_extent_buffer(eb, namebuf, (unsigned long)(ref + 1), len);
73                 printf("\t\tinode ref index %llu namelen %u name: %.*s\n",
74                        (unsigned long long)index, name_len, len, namebuf);
75                 len = sizeof(*ref) + name_len;
76                 ref = (struct btrfs_inode_ref *)((char *)ref + len);
77                 cur += len;
78         }
79         return 0;
80 }
81
82 static void print_chunk(struct extent_buffer *eb, struct btrfs_chunk *chunk)
83 {
84         int num_stripes = btrfs_chunk_num_stripes(eb, chunk);
85         int i;
86         printf("\t\tchunk length %llu owner %llu type %llu num_stripes %d\n",
87                (unsigned long long)btrfs_chunk_length(eb, chunk),
88                (unsigned long long)btrfs_chunk_owner(eb, chunk),
89                (unsigned long long)btrfs_chunk_type(eb, chunk),
90                num_stripes);
91         for (i = 0 ; i < num_stripes ; i++) {
92                 printf("\t\t\tstripe %d devid %llu offset %llu\n", i,
93                       (unsigned long long)btrfs_stripe_devid_nr(eb, chunk, i),
94                       (unsigned long long)btrfs_stripe_offset_nr(eb, chunk, i));
95         }
96 }
97 static void print_dev_item(struct extent_buffer *eb,
98                            struct btrfs_dev_item *dev_item)
99 {
100         printf("\t\tdev item devid %llu "
101                "total_bytes %llu bytes used %Lu\n",
102                (unsigned long long)btrfs_device_id(eb, dev_item),
103                (unsigned long long)btrfs_device_total_bytes(eb, dev_item),
104                (unsigned long long)btrfs_device_bytes_used(eb, dev_item));
105 }
106
107 static void print_uuids(struct extent_buffer *eb)
108 {
109         char fs_uuid[37];
110         char chunk_uuid[37];
111         u8 disk_uuid[BTRFS_UUID_SIZE];
112
113         read_extent_buffer(eb, disk_uuid, (unsigned long)btrfs_header_fsid(eb),
114                            BTRFS_FSID_SIZE);
115
116         fs_uuid[36] = '\0';
117         uuid_unparse(disk_uuid, fs_uuid);
118
119         read_extent_buffer(eb, disk_uuid,
120                            (unsigned long)btrfs_header_chunk_tree_uuid(eb),
121                            BTRFS_UUID_SIZE);
122
123         chunk_uuid[36] = '\0';
124         uuid_unparse(disk_uuid, chunk_uuid);
125         printf("fs uuid %s\nchunk uuid %s\n", fs_uuid, chunk_uuid);
126 }
127
128 static void print_file_extent_item(struct extent_buffer *eb,
129                                    struct btrfs_item *item,
130                                    struct btrfs_file_extent_item *fi)
131 {
132         int extent_type = btrfs_file_extent_type(eb, fi);
133
134         if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
135                 printf("\t\tinline extent data size %u "
136                        "ram %u compress %d\n",
137                   btrfs_file_extent_inline_item_len(eb, item),
138                   btrfs_file_extent_inline_len(eb, fi),
139                   btrfs_file_extent_compression(eb, fi));
140                 return;
141         }
142         if (extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
143                 printf("\t\tprealloc data disk byte %llu nr %llu\n",
144                   (unsigned long long)btrfs_file_extent_disk_bytenr(eb, fi),
145                   (unsigned long long)btrfs_file_extent_disk_num_bytes(eb, fi));
146                 printf("\t\tprealloc data offset %llu nr %llu\n",
147                   (unsigned long long)btrfs_file_extent_offset(eb, fi),
148                   (unsigned long long)btrfs_file_extent_num_bytes(eb, fi));
149                 return;
150         }
151         printf("\t\textent data disk byte %llu nr %llu\n",
152                 (unsigned long long)btrfs_file_extent_disk_bytenr(eb, fi),
153                 (unsigned long long)btrfs_file_extent_disk_num_bytes(eb, fi));
154         printf("\t\textent data offset %llu nr %llu ram %llu\n",
155                 (unsigned long long)btrfs_file_extent_offset(eb, fi),
156                 (unsigned long long)btrfs_file_extent_num_bytes(eb, fi),
157                 (unsigned long long)btrfs_file_extent_ram_bytes(eb, fi));
158         printf("\t\textent compression %d\n",
159                btrfs_file_extent_compression(eb, fi));
160 }
161
162 static void print_extent_item(struct extent_buffer *eb, int slot)
163 {
164         struct btrfs_extent_item *ei;
165         struct btrfs_extent_inline_ref *iref;
166         struct btrfs_extent_data_ref *dref;
167         struct btrfs_shared_data_ref *sref;
168         struct btrfs_disk_key key;
169         unsigned long end;
170         unsigned long ptr;
171         int type;
172         u32 item_size = btrfs_item_size_nr(eb, slot);
173         u64 flags;
174         u64 offset;
175
176         if (item_size < sizeof(*ei)) {
177 #ifdef BTRFS_COMPAT_EXTENT_TREE_V0
178                 struct btrfs_extent_item_v0 *ei0;
179                 BUG_ON(item_size != sizeof(*ei0));
180                 ei0 = btrfs_item_ptr(eb, slot, struct btrfs_extent_item_v0);
181                 printf("\t\textent refs %u\n",
182                        btrfs_extent_refs_v0(eb, ei0));
183                 return;
184 #else
185                 BUG();
186 #endif
187         }
188
189         ei = btrfs_item_ptr(eb, slot, struct btrfs_extent_item);
190         flags = btrfs_extent_flags(eb, ei);
191
192         printf("\t\textent refs %llu gen %llu flags %llu\n",
193                (unsigned long long)btrfs_extent_refs(eb, ei),
194                (unsigned long long)btrfs_extent_generation(eb, ei),
195                (unsigned long long)flags);
196
197         if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
198                 struct btrfs_tree_block_info *info;
199                 info = (struct btrfs_tree_block_info *)(ei + 1);
200                 btrfs_tree_block_key(eb, info, &key);
201                 printf("\t\ttree block key (%llu %x %llu) level %d\n",
202                        (unsigned long long)btrfs_disk_key_objectid(&key),
203                        key.type,
204                        (unsigned long long)btrfs_disk_key_offset(&key),
205                        btrfs_tree_block_level(eb, info));
206                 iref = (struct btrfs_extent_inline_ref *)(info + 1);
207         } else {
208                 iref = (struct btrfs_extent_inline_ref *)(ei + 1);
209         }
210
211         ptr = (unsigned long)iref;
212         end = (unsigned long)ei + item_size;
213         while (ptr < end) {
214                 iref = (struct btrfs_extent_inline_ref *)ptr;
215                 type = btrfs_extent_inline_ref_type(eb, iref);
216                 offset = btrfs_extent_inline_ref_offset(eb, iref);
217                 switch (type) {
218                 case BTRFS_TREE_BLOCK_REF_KEY:
219                         printf("\t\ttree block backref root %llu\n",
220                                (unsigned long long)offset);
221                         break;
222                 case BTRFS_SHARED_BLOCK_REF_KEY:
223                         printf("\t\tshared block backref parent %llu\n",
224                                (unsigned long long)offset);
225                         break;
226                 case BTRFS_EXTENT_DATA_REF_KEY:
227                         dref = (struct btrfs_extent_data_ref *)(&iref->offset);
228                         printf("\t\textent data backref root %llu "
229                                "objectid %llu offset %llu count %u\n",
230                                (unsigned long long)btrfs_extent_data_ref_root(eb, dref),
231                                (unsigned long long)btrfs_extent_data_ref_objectid(eb, dref),
232                                (unsigned long long)btrfs_extent_data_ref_offset(eb, dref),
233                                btrfs_extent_data_ref_count(eb, dref));
234                         break;
235                 case BTRFS_SHARED_DATA_REF_KEY:
236                         sref = (struct btrfs_shared_data_ref *)(iref + 1);
237                         printf("\t\tshared data backref parent %llu count %u\n",
238                                (unsigned long long)offset,
239                                btrfs_shared_data_ref_count(eb, sref));
240                         break;
241                 default:
242                         return;
243                 }
244                 ptr += btrfs_extent_inline_ref_size(type);
245         }
246         WARN_ON(ptr > end);
247 }
248
249 #ifdef BTRFS_COMPAT_EXTENT_TREE_V0
250 static void print_extent_ref_v0(struct extent_buffer *eb, int slot)
251 {
252         struct btrfs_extent_ref_v0 *ref0;
253
254         ref0 = btrfs_item_ptr(eb, slot, struct btrfs_extent_ref_v0);
255         printf("\t\textent back ref root %llu gen %llu "
256                 "owner %llu num_refs %lu\n",
257                 (unsigned long long)btrfs_ref_root_v0(eb, ref0),
258                 (unsigned long long)btrfs_ref_generation_v0(eb, ref0),
259                 (unsigned long long)btrfs_ref_objectid_v0(eb, ref0),
260                 (unsigned long)btrfs_ref_count_v0(eb, ref0));
261 }
262 #endif
263
264 static void print_root_ref(struct extent_buffer *leaf, int slot, char *tag)
265 {
266         struct btrfs_root_ref *ref;
267         char namebuf[BTRFS_NAME_LEN];
268         int namelen;
269
270         ref = btrfs_item_ptr(leaf, slot, struct btrfs_root_ref);
271         namelen = btrfs_root_ref_name_len(leaf, ref);
272         read_extent_buffer(leaf, namebuf, (unsigned long)(ref + 1), namelen);
273         printf("\t\troot %s key dirid %llu sequence %llu name %.*s\n", tag,
274                (unsigned long long)btrfs_root_ref_dirid(leaf, ref),
275                (unsigned long long)btrfs_root_ref_sequence(leaf, ref),
276                namelen, namebuf);
277 }
278
279 static void print_key_type(u8 type)
280 {
281         switch (type) {
282         case BTRFS_INODE_ITEM_KEY:
283                 printf("INODE_ITEM");
284                 break;
285         case BTRFS_INODE_REF_KEY:
286                 printf("INODE_REF");
287                 break;
288         case BTRFS_DIR_ITEM_KEY:
289                 printf("DIR_ITEM");
290                 break;
291         case BTRFS_DIR_INDEX_KEY:
292                 printf("DIR_INDEX");
293                 break;
294         case BTRFS_DIR_LOG_ITEM_KEY:
295                 printf("DIR_LOG_ITEM");
296                 break;
297         case BTRFS_DIR_LOG_INDEX_KEY:
298                 printf("DIR_LOG_INDEX");
299                 break;
300         case BTRFS_XATTR_ITEM_KEY:
301                 printf("XATTR_ITEM");
302                 break;
303         case BTRFS_ORPHAN_ITEM_KEY:
304                 printf("ORPHAN_ITEM");
305                 break;
306         case BTRFS_ROOT_ITEM_KEY:
307                 printf("ROOT_ITEM");
308                 break;
309         case BTRFS_ROOT_REF_KEY:
310                 printf("ROOT_REF");
311                 break;
312         case BTRFS_ROOT_BACKREF_KEY:
313                 printf("ROOT_BACKREF");
314                 break;
315         case BTRFS_EXTENT_ITEM_KEY:
316                 printf("EXTENT_ITEM");
317                 break;
318         case BTRFS_TREE_BLOCK_REF_KEY:
319                 printf("TREE_BLOCK_REF");
320                 break;
321         case BTRFS_SHARED_BLOCK_REF_KEY:
322                 printf("SHARED_BLOCK_REF");
323                 break;
324         case BTRFS_EXTENT_DATA_REF_KEY:
325                 printf("EXTENT_DATA_REF");
326                 break;
327         case BTRFS_SHARED_DATA_REF_KEY:
328                 printf("SHARED_DATA_REF");
329                 break;
330         case BTRFS_EXTENT_REF_V0_KEY:
331                 printf("EXTENT_REF_V0");
332                 break;
333         case BTRFS_CSUM_ITEM_KEY:
334                 printf("CSUM_ITEM");
335                 break;
336         case BTRFS_EXTENT_CSUM_KEY:
337                 printf("EXTENT_CSUM");
338                 break;
339         case BTRFS_EXTENT_DATA_KEY:
340                 printf("EXTENT_DATA");
341                 break;
342         case BTRFS_BLOCK_GROUP_ITEM_KEY:
343                 printf("BLOCK_GROUP_ITEM");
344                 break;
345         case BTRFS_CHUNK_ITEM_KEY:
346                 printf("CHUNK_ITEM");
347                 break;
348         case BTRFS_DEV_ITEM_KEY:
349                 printf("DEV_ITEM");
350                 break;
351         case BTRFS_DEV_EXTENT_KEY:
352                 printf("DEV_EXTENT");
353                 break;
354         case BTRFS_BALANCE_ITEM_KEY:
355                 printf("BALANCE_ITEM");
356                 break;
357         case BTRFS_STRING_ITEM_KEY:
358                 printf("STRING_ITEM");
359                 break;
360         default:
361                 printf("UNKNOWN");
362         };
363 }
364
365 static void print_objectid(unsigned long long objectid, u8 type)
366 {
367         if (type == BTRFS_DEV_EXTENT_KEY) {
368                 printf("%llu", objectid); /* device id */
369                 return;
370         }
371
372         switch (objectid) {
373         case BTRFS_ROOT_TREE_OBJECTID:
374                 if (type == BTRFS_DEV_ITEM_KEY)
375                         printf("DEV_ITEMS");
376                 else
377                         printf("ROOT_TREE");
378                 break;
379         case BTRFS_EXTENT_TREE_OBJECTID:
380                 printf("EXTENT_TREE");
381                 break;
382         case BTRFS_CHUNK_TREE_OBJECTID:
383                 printf("CHUNK_TREE");
384                 break;
385         case BTRFS_DEV_TREE_OBJECTID:
386                 printf("DEV_TREE");
387                 break;
388         case BTRFS_FS_TREE_OBJECTID:
389                 printf("FS_TREE");
390                 break;
391         case BTRFS_ROOT_TREE_DIR_OBJECTID:
392                 printf("ROOT_TREE_DIR");
393                 break;
394         case BTRFS_CSUM_TREE_OBJECTID:
395                 printf("CSUM_TREE");
396                 break;
397         case BTRFS_BALANCE_OBJECTID:
398                 printf("BALANCE");
399                 break;
400         case BTRFS_ORPHAN_OBJECTID:
401                 printf("ORPHAN");
402                 break;
403         case BTRFS_TREE_LOG_OBJECTID:
404                 printf("TREE_LOG");
405                 break;
406         case BTRFS_TREE_LOG_FIXUP_OBJECTID:
407                 printf("LOG_FIXUP");
408                 break;
409         case BTRFS_TREE_RELOC_OBJECTID:
410                 printf("TREE_RELOC");
411                 break;
412         case BTRFS_DATA_RELOC_TREE_OBJECTID:
413                 printf("DATA_RELOC_TREE");
414                 break;
415         case BTRFS_EXTENT_CSUM_OBJECTID:
416                 printf("EXTENT_CSUM");
417                 break;
418         case BTRFS_MULTIPLE_OBJECTIDS:
419                 printf("MULTIPLE");
420                 break;
421         case BTRFS_FIRST_CHUNK_TREE_OBJECTID:
422                 if (type == BTRFS_CHUNK_ITEM_KEY) {
423                         printf("FIRST_CHUNK_TREE");
424                         break;
425                 }
426                 /* fall-thru */
427         default:
428                 printf("%llu", objectid);
429         }
430 }
431
432 void btrfs_print_key(struct btrfs_disk_key *disk_key)
433 {
434         u8 type;
435         printf("key (");
436         type = btrfs_disk_key_type(disk_key);
437         print_objectid((unsigned long long)btrfs_disk_key_objectid(disk_key),
438                 type);
439         printf(" ");
440         print_key_type(type);
441         printf(" %llu)", (unsigned long long)btrfs_disk_key_offset(disk_key));
442 }
443
444 void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
445 {
446         int i;
447         char *str;
448         struct btrfs_item *item;
449         struct btrfs_root_item *ri;
450         struct btrfs_dir_item *di;
451         struct btrfs_inode_item *ii;
452         struct btrfs_file_extent_item *fi;
453         struct btrfs_block_group_item *bi;
454         struct btrfs_extent_data_ref *dref;
455         struct btrfs_shared_data_ref *sref;
456         struct btrfs_inode_ref *iref;
457         struct btrfs_dev_extent *dev_extent;
458         struct btrfs_disk_key disk_key;
459         struct btrfs_root_item root_item;
460         struct btrfs_block_group_item bg_item;
461         struct btrfs_dir_log_item *dlog;
462         u32 nr = btrfs_header_nritems(l);
463         u32 type;
464
465         printf("leaf %llu items %d free space %d generation %llu owner %llu\n",
466                 (unsigned long long)btrfs_header_bytenr(l), nr,
467                 btrfs_leaf_free_space(root, l),
468                 (unsigned long long)btrfs_header_generation(l),
469                 (unsigned long long)btrfs_header_owner(l));
470         print_uuids(l);
471         fflush(stdout);
472         for (i = 0 ; i < nr ; i++) {
473                 item = btrfs_item_nr(l, i);
474                 btrfs_item_key(l, &disk_key, i);
475                 type = btrfs_disk_key_type(&disk_key);
476                 printf("\titem %d ", i);
477                 btrfs_print_key(&disk_key);
478                 printf(" itemoff %d itemsize %d\n",
479                         btrfs_item_offset(l, item),
480                         btrfs_item_size(l, item));
481                 switch (type) {
482                 case BTRFS_INODE_ITEM_KEY:
483                         ii = btrfs_item_ptr(l, i, struct btrfs_inode_item);
484                         printf("\t\tinode generation %llu size %llu block group %llu mode %o links %u\n",
485                                (unsigned long long)btrfs_inode_generation(l, ii),
486                                (unsigned long long)btrfs_inode_size(l, ii),
487                                (unsigned long long)btrfs_inode_block_group(l,ii),
488                                btrfs_inode_mode(l, ii),
489                                btrfs_inode_nlink(l, ii));
490                         break;
491                 case BTRFS_INODE_REF_KEY:
492                         iref = btrfs_item_ptr(l, i, struct btrfs_inode_ref);
493                         print_inode_ref_item(l, item, iref);
494                         break;
495                 case BTRFS_DIR_ITEM_KEY:
496                 case BTRFS_DIR_INDEX_KEY:
497                 case BTRFS_XATTR_ITEM_KEY:
498                         di = btrfs_item_ptr(l, i, struct btrfs_dir_item);
499                         print_dir_item(l, item, di);
500                         break;
501                 case BTRFS_DIR_LOG_INDEX_KEY:
502                 case BTRFS_DIR_LOG_ITEM_KEY:
503                         dlog = btrfs_item_ptr(l, i, struct btrfs_dir_log_item);
504                         printf("\t\tdir log end %Lu\n",
505                                (unsigned long long)btrfs_dir_log_end(l, dlog));
506                        break;
507                 case BTRFS_ORPHAN_ITEM_KEY:
508                         printf("\t\torphan item\n");
509                         break;
510                 case BTRFS_ROOT_ITEM_KEY:
511                         ri = btrfs_item_ptr(l, i, struct btrfs_root_item);
512                         read_extent_buffer(l, &root_item, (unsigned long)ri, sizeof(root_item));
513                         printf("\t\troot data bytenr %llu level %d dirid %llu refs %u gen %llu\n",
514                                 (unsigned long long)btrfs_root_bytenr(&root_item),
515                                 btrfs_root_level(&root_item),
516                                 (unsigned long long)btrfs_root_dirid(&root_item),
517                                 btrfs_root_refs(&root_item),
518                                 (unsigned long long)btrfs_root_generation(&root_item));
519                         if (btrfs_root_refs(&root_item) == 0) {
520                                 struct btrfs_key drop_key;
521                                 btrfs_disk_key_to_cpu(&drop_key,
522                                                       &root_item.drop_progress);
523                                 printf("\t\tdrop ");
524                                 btrfs_print_key(&root_item.drop_progress);
525                                 printf(" level %d\n", root_item.drop_level);
526                         }
527                         break;
528                 case BTRFS_ROOT_REF_KEY:
529                         print_root_ref(l, i, "ref");
530                         break;
531                 case BTRFS_ROOT_BACKREF_KEY:
532                         print_root_ref(l, i, "backref");
533                         break;
534                 case BTRFS_EXTENT_ITEM_KEY:
535                         print_extent_item(l, i);
536                         break;
537                 case BTRFS_TREE_BLOCK_REF_KEY:
538                         printf("\t\ttree block backref\n");
539                         break;
540                 case BTRFS_SHARED_BLOCK_REF_KEY:
541                         printf("\t\tshared block backref\n");
542                         break;
543                 case BTRFS_EXTENT_DATA_REF_KEY:
544                         dref = btrfs_item_ptr(l, i, struct btrfs_extent_data_ref);
545                         printf("\t\textent data backref root %llu "
546                                "objectid %llu offset %llu count %u\n",
547                                (unsigned long long)btrfs_extent_data_ref_root(l, dref),
548                                (unsigned long long)btrfs_extent_data_ref_objectid(l, dref),
549                                (unsigned long long)btrfs_extent_data_ref_offset(l, dref),
550                                btrfs_extent_data_ref_count(l, dref));
551                         break;
552                 case BTRFS_SHARED_DATA_REF_KEY:
553                         sref = btrfs_item_ptr(l, i, struct btrfs_shared_data_ref);
554                         printf("\t\tshared data backref count %u\n",
555                                btrfs_shared_data_ref_count(l, sref));
556                         break;
557                 case BTRFS_EXTENT_REF_V0_KEY:
558 #ifdef BTRFS_COMPAT_EXTENT_TREE_V0
559                         print_extent_ref_v0(l, i);
560 #else
561                         BUG();
562 #endif
563                         break;
564                 case BTRFS_CSUM_ITEM_KEY:
565                         printf("\t\tcsum item\n");
566                         break;
567                 case BTRFS_EXTENT_CSUM_KEY:
568                         printf("\t\textent csum item\n");
569                         break;
570                 case BTRFS_EXTENT_DATA_KEY:
571                         fi = btrfs_item_ptr(l, i,
572                                             struct btrfs_file_extent_item);
573                         print_file_extent_item(l, item, fi);
574                         break;
575                 case BTRFS_BLOCK_GROUP_ITEM_KEY:
576                         bi = btrfs_item_ptr(l, i,
577                                             struct btrfs_block_group_item);
578                         read_extent_buffer(l, &bg_item, (unsigned long)bi,
579                                            sizeof(bg_item));
580                         printf("\t\tblock group used %llu chunk_objectid %llu flags %llu\n",
581                                (unsigned long long)btrfs_block_group_used(&bg_item),
582                                (unsigned long long)btrfs_block_group_chunk_objectid(&bg_item),
583                                (unsigned long long)btrfs_block_group_flags(&bg_item));
584                         break;
585                 case BTRFS_CHUNK_ITEM_KEY:
586                         print_chunk(l, btrfs_item_ptr(l, i, struct btrfs_chunk));
587                         break;
588                 case BTRFS_DEV_ITEM_KEY:
589                         print_dev_item(l, btrfs_item_ptr(l, i,
590                                         struct btrfs_dev_item));
591                         break;
592                 case BTRFS_DEV_EXTENT_KEY:
593                         dev_extent = btrfs_item_ptr(l, i,
594                                                     struct btrfs_dev_extent);
595                         printf("\t\tdev extent chunk_tree %llu\n"
596                                "\t\tchunk objectid %llu chunk offset %llu "
597                                "length %llu\n",
598                                (unsigned long long)
599                                btrfs_dev_extent_chunk_tree(l, dev_extent),
600                                (unsigned long long)
601                                btrfs_dev_extent_chunk_objectid(l, dev_extent),
602                                (unsigned long long)
603                                btrfs_dev_extent_chunk_offset(l, dev_extent),
604                                (unsigned long long)
605                                btrfs_dev_extent_length(l, dev_extent));
606                         break;
607                 case BTRFS_STRING_ITEM_KEY:
608                         /* dirty, but it's simple */
609                         str = l->data + btrfs_item_ptr_offset(l, i);
610                         printf("\t\titem data %.*s\n", btrfs_item_size(l, item), str);
611                         break;
612                 };
613                 fflush(stdout);
614         }
615 }
616
617 void btrfs_print_tree(struct btrfs_root *root, struct extent_buffer *eb, int follow)
618 {
619         int i;
620         u32 nr;
621         u32 size;
622         struct btrfs_disk_key disk_key;
623         struct btrfs_key key;
624
625         if (!eb)
626                 return;
627         nr = btrfs_header_nritems(eb);
628         if (btrfs_is_leaf(eb)) {
629                 btrfs_print_leaf(root, eb);
630                 return;
631         }
632         printf("node %llu level %d items %d free %u generation %llu owner %llu\n",
633                (unsigned long long)eb->start,
634                 btrfs_header_level(eb), nr,
635                 (u32)BTRFS_NODEPTRS_PER_BLOCK(root) - nr,
636                 (unsigned long long)btrfs_header_generation(eb),
637                 (unsigned long long)btrfs_header_owner(eb));
638         print_uuids(eb);
639         fflush(stdout);
640         size = btrfs_level_size(root, btrfs_header_level(eb) - 1);
641         for (i = 0; i < nr; i++) {
642                 u64 blocknr = btrfs_node_blockptr(eb, i);
643                 btrfs_node_key(eb, &disk_key, i);
644                 btrfs_disk_key_to_cpu(&key, &disk_key);
645                 printf("\t");
646                 btrfs_print_key(&disk_key);
647                 printf(" block %llu (%llu) gen %llu\n",
648                        (unsigned long long)blocknr,
649                        (unsigned long long)blocknr / size,
650                        (unsigned long long)btrfs_node_ptr_generation(eb, i));
651                 fflush(stdout);
652         }
653         if (!follow)
654                 return;
655
656         for (i = 0; i < nr; i++) {
657                 struct extent_buffer *next = read_tree_block(root,
658                                              btrfs_node_blockptr(eb, i),
659                                              size,
660                                              btrfs_node_ptr_generation(eb, i));
661                 if (!next) {
662                         fprintf(stderr, "failed to read %llu in tree %llu\n",
663                                 (unsigned long long)btrfs_node_blockptr(eb, i),
664                                 (unsigned long long)btrfs_header_owner(eb));
665                         continue;
666                 }
667                 if (btrfs_is_leaf(next) &&
668                     btrfs_header_level(eb) != 1)
669                         BUG();
670                 if (btrfs_header_level(next) !=
671                         btrfs_header_level(eb) - 1)
672                         BUG();
673                 btrfs_print_tree(root, next, 1);
674                 free_extent_buffer(next);
675         }
676 }