Fix printf format casting errors
[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
163 static void print_root_ref(struct extent_buffer *leaf, int slot, char *tag)
164 {
165         struct btrfs_root_ref *ref;
166         char namebuf[BTRFS_NAME_LEN];
167         int namelen;
168
169         ref = btrfs_item_ptr(leaf, slot, struct btrfs_root_ref);
170         namelen = btrfs_root_ref_name_len(leaf, ref);
171         read_extent_buffer(leaf, namebuf, (unsigned long)(ref + 1), namelen);
172         printf("\t\troot %s key dirid %llu sequence %llu name %.*s\n", tag,
173                (unsigned long long)btrfs_root_ref_dirid(leaf, ref),
174                (unsigned long long)btrfs_root_ref_sequence(leaf, ref),
175                namelen, namebuf);
176 }
177
178 static void print_key_type(u8 type)
179 {
180         switch (type) {
181         case BTRFS_INODE_ITEM_KEY:
182                 printf("INODE_ITEM");
183                 break;
184         case BTRFS_INODE_REF_KEY:
185                 printf("INODE_REF");
186                 break;
187         case BTRFS_DIR_ITEM_KEY:
188                 printf("DIR_ITEM");
189                 break;
190         case BTRFS_DIR_INDEX_KEY:
191                 printf("DIR_INDEX");
192                 break;
193         case BTRFS_DIR_LOG_ITEM_KEY:
194                 printf("DIR_LOG_ITEM");
195                 break;
196         case BTRFS_DIR_LOG_INDEX_KEY:
197                 printf("DIR_LOG_INDEX");
198                 break;
199         case BTRFS_XATTR_ITEM_KEY:
200                 printf("XATTR_ITEM");
201                 break;
202         case BTRFS_ORPHAN_ITEM_KEY:
203                 printf("ORPHAN_ITEM");
204                 break;
205         case BTRFS_ROOT_ITEM_KEY:
206                 printf("ROOT_ITEM");
207                 break;
208         case BTRFS_ROOT_REF_KEY:
209                 printf("ROOT_REF");
210                 break;
211         case BTRFS_ROOT_BACKREF_KEY:
212                 printf("ROOT_BACKREF");
213                 break;
214         case BTRFS_EXTENT_ITEM_KEY:
215                 printf("EXTENT_ITEM");
216                 break;
217         case BTRFS_EXTENT_REF_KEY:
218                 printf("EXTENT_REF");
219                 break;
220         case BTRFS_CSUM_ITEM_KEY:
221                 printf("CSUM_ITEM");
222                 break;
223         case BTRFS_EXTENT_CSUM_KEY:
224                 printf("EXTENT_CSUM");
225                 break;
226         case BTRFS_EXTENT_DATA_KEY:
227                 printf("EXTENT_DATA");
228                 break;
229         case BTRFS_BLOCK_GROUP_ITEM_KEY:
230                 printf("BLOCK_GROUP_ITEM");
231                 break;
232         case BTRFS_CHUNK_ITEM_KEY:
233                 printf("CHUNK_ITEM");
234                 break;
235         case BTRFS_DEV_ITEM_KEY:
236                 printf("DEV_ITEM");
237                 break;
238         case BTRFS_DEV_EXTENT_KEY:
239                 printf("DEV_EXTENT");
240                 break;
241         case BTRFS_STRING_ITEM_KEY:
242                 printf("STRING_ITEM");
243                 break;
244         default:
245                 printf("UNKNOWN");
246         };
247 }
248
249 static void print_objectid(unsigned long long objectid, u8 type)
250 {
251         if (type == BTRFS_DEV_EXTENT_KEY) {
252                 printf("%llu", objectid); /* device id */
253                 return;
254         }
255
256         switch (objectid) {
257         case BTRFS_ROOT_TREE_OBJECTID:
258                 if (type == BTRFS_DEV_ITEM_KEY)
259                         printf("DEV_ITEMS");
260                 else
261                         printf("ROOT_TREE");
262                 break;
263         case BTRFS_EXTENT_TREE_OBJECTID:
264                 printf("EXTENT_TREE");
265                 break;
266         case BTRFS_CHUNK_TREE_OBJECTID:
267                 printf("CHUNK_TREE");
268                 break;
269         case BTRFS_DEV_TREE_OBJECTID:
270                 printf("DEV_TREE");
271                 break;
272         case BTRFS_FS_TREE_OBJECTID:
273                 printf("FS_TREE");
274                 break;
275         case BTRFS_ROOT_TREE_DIR_OBJECTID:
276                 printf("ROOT_TREE_DIR");
277                 break;
278         case BTRFS_CSUM_TREE_OBJECTID:
279                 printf("CSUM_TREE");
280                 break;
281         case BTRFS_ORPHAN_OBJECTID:
282                 printf("ORPHAN");
283                 break;
284         case BTRFS_TREE_LOG_OBJECTID:
285                 printf("TREE_LOG");
286                 break;
287         case BTRFS_TREE_LOG_FIXUP_OBJECTID:
288                 printf("LOG_FIXUP");
289                 break;
290         case BTRFS_TREE_RELOC_OBJECTID:
291                 printf("TREE_RELOC");
292                 break;
293         case BTRFS_DATA_RELOC_TREE_OBJECTID:
294                 printf("DATA_RELOC_TREE");
295                 break;
296         case BTRFS_EXTENT_CSUM_OBJECTID:
297                 printf("EXTENT_CSUM");
298                 break;
299         case BTRFS_MULTIPLE_OBJECTIDS:
300                 printf("MULTIPLE");
301                 break;
302         case BTRFS_FIRST_CHUNK_TREE_OBJECTID:
303                 printf("FIRST_CHUNK_TREE");
304                 break;
305         default:
306                 printf("%llu", objectid);
307         }
308 }
309
310 void btrfs_print_key(struct btrfs_disk_key *disk_key)
311 {
312         u8 type;
313         printf("key (");
314         type = btrfs_disk_key_type(disk_key);
315         print_objectid((unsigned long long)btrfs_disk_key_objectid(disk_key),
316                 type);
317         printf(" ");
318         print_key_type(type);
319         printf(" %llu)", (unsigned long long)btrfs_disk_key_offset(disk_key));
320 }
321
322 void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
323 {
324         int i;
325         char *str;
326         struct btrfs_item *item;
327         struct btrfs_extent_item *ei;
328         struct btrfs_root_item *ri;
329         struct btrfs_dir_item *di;
330         struct btrfs_inode_item *ii;
331         struct btrfs_file_extent_item *fi;
332         struct btrfs_csum_item *ci;
333         struct btrfs_block_group_item *bi;
334         struct btrfs_extent_ref *ref;
335         struct btrfs_inode_ref *iref;
336         struct btrfs_dev_extent *dev_extent;
337         struct btrfs_disk_key disk_key;
338         struct btrfs_root_item root_item;
339         struct btrfs_block_group_item bg_item;
340         struct btrfs_dir_log_item *dlog;
341         u32 nr = btrfs_header_nritems(l);
342         u32 type;
343
344         printf("leaf %llu items %d free space %d generation %llu owner %llu\n",
345                 (unsigned long long)btrfs_header_bytenr(l), nr,
346                 btrfs_leaf_free_space(root, l),
347                 (unsigned long long)btrfs_header_generation(l),
348                 (unsigned long long)btrfs_header_owner(l));
349         print_uuids(l);
350         fflush(stdout);
351         for (i = 0 ; i < nr ; i++) {
352                 item = btrfs_item_nr(l, i);
353                 btrfs_item_key(l, &disk_key, i);
354                 type = btrfs_disk_key_type(&disk_key);
355                 printf("\titem %d ", i);
356                 btrfs_print_key(&disk_key);
357                 printf(" itemoff %d itemsize %d\n",
358                         btrfs_item_offset(l, item),
359                         btrfs_item_size(l, item));
360                 switch (type) {
361                 case BTRFS_INODE_ITEM_KEY:
362                         ii = btrfs_item_ptr(l, i, struct btrfs_inode_item);
363                         printf("\t\tinode generation %llu size %llu block group %llu mode %o links %u\n",
364                                (unsigned long long)btrfs_inode_generation(l, ii),
365                                (unsigned long long)btrfs_inode_size(l, ii),
366                                (unsigned long long)btrfs_inode_block_group(l,ii),
367                                btrfs_inode_mode(l, ii),
368                                btrfs_inode_nlink(l, ii));
369                         break;
370                 case BTRFS_INODE_REF_KEY:
371                         iref = btrfs_item_ptr(l, i, struct btrfs_inode_ref);
372                         print_inode_ref_item(l, item, iref);
373                         break;
374                 case BTRFS_DIR_ITEM_KEY:
375                 case BTRFS_DIR_INDEX_KEY:
376                 case BTRFS_XATTR_ITEM_KEY:
377                         di = btrfs_item_ptr(l, i, struct btrfs_dir_item);
378                         print_dir_item(l, item, di);
379                         break;
380                 case BTRFS_DIR_LOG_INDEX_KEY:
381                 case BTRFS_DIR_LOG_ITEM_KEY:
382                         dlog = btrfs_item_ptr(l, i, struct btrfs_dir_log_item);
383                         printf("\t\tdir log end %Lu\n",
384                                btrfs_dir_log_end(l, dlog));
385                        break;
386                 case BTRFS_ORPHAN_ITEM_KEY:
387                         printf("\t\torphan item\n");
388                         break;
389                 case BTRFS_ROOT_ITEM_KEY:
390                         ri = btrfs_item_ptr(l, i, struct btrfs_root_item);
391                         read_extent_buffer(l, &root_item, (unsigned long)ri, sizeof(root_item));
392                         printf("\t\troot data bytenr %llu level %d dirid %llu refs %u\n",
393                                 (unsigned long long)btrfs_root_bytenr(&root_item),
394                                 btrfs_root_level(&root_item),
395                                 (unsigned long long)btrfs_root_dirid(&root_item),
396                                 btrfs_root_refs(&root_item));
397                         if (btrfs_root_refs(&root_item) == 0) {
398                                 struct btrfs_key drop_key;
399                                 btrfs_disk_key_to_cpu(&drop_key,
400                                                       &root_item.drop_progress);
401                                 printf("\t\tdrop ");
402                                 btrfs_print_key(&root_item.drop_progress);
403                                 printf(" level %d\n", root_item.drop_level);
404                         }
405                         break;
406                 case BTRFS_ROOT_REF_KEY:
407                         print_root_ref(l, i, "ref");
408                         break;
409                 case BTRFS_ROOT_BACKREF_KEY:
410                         print_root_ref(l, i, "backref");
411                         break;
412                 case BTRFS_EXTENT_ITEM_KEY:
413                         ei = btrfs_item_ptr(l, i, struct btrfs_extent_item);
414                         printf("\t\textent data refs %u\n",
415                                 btrfs_extent_refs(l, ei));
416                         break;
417                 case BTRFS_EXTENT_REF_KEY:
418                         ref = btrfs_item_ptr(l, i, struct btrfs_extent_ref);
419                         printf("\t\textent back ref root %llu gen %llu "
420                                "owner %llu num_refs %lu\n",
421                                (unsigned long long)btrfs_ref_root(l, ref),
422                                (unsigned long long)btrfs_ref_generation(l, ref),
423                                (unsigned long long)btrfs_ref_objectid(l, ref),
424                                (unsigned long)btrfs_ref_num_refs(l, ref));
425                         break;
426                 case BTRFS_CSUM_ITEM_KEY:
427                         ci = btrfs_item_ptr(l, i, struct btrfs_csum_item);
428                         printf("\t\tcsum item\n");
429                         break;
430                 case BTRFS_EXTENT_CSUM_KEY:
431                         ci = btrfs_item_ptr(l, i, struct btrfs_csum_item);
432                         printf("\t\textent csum item\n");
433                         break;
434                 case BTRFS_EXTENT_DATA_KEY:
435                         fi = btrfs_item_ptr(l, i,
436                                             struct btrfs_file_extent_item);
437                         print_file_extent_item(l, item, fi);
438                         break;
439                 case BTRFS_BLOCK_GROUP_ITEM_KEY:
440                         bi = btrfs_item_ptr(l, i,
441                                             struct btrfs_block_group_item);
442                         read_extent_buffer(l, &bg_item, (unsigned long)bi,
443                                            sizeof(bg_item));
444                         printf("\t\tblock group used %llu chunk_objectid %llu flags %llu\n",
445                                (unsigned long long)btrfs_block_group_used(&bg_item),
446                                (unsigned long long)btrfs_block_group_chunk_objectid(&bg_item),
447                                (unsigned long long)btrfs_block_group_flags(&bg_item));
448                         break;
449                 case BTRFS_CHUNK_ITEM_KEY:
450                         print_chunk(l, btrfs_item_ptr(l, i, struct btrfs_chunk));
451                         break;
452                 case BTRFS_DEV_ITEM_KEY:
453                         print_dev_item(l, btrfs_item_ptr(l, i,
454                                         struct btrfs_dev_item));
455                         break;
456                 case BTRFS_DEV_EXTENT_KEY:
457                         dev_extent = btrfs_item_ptr(l, i,
458                                                     struct btrfs_dev_extent);
459                         printf("\t\tdev extent chunk_tree %llu\n"
460                                "\t\tchunk objectid %llu chunk offset %llu "
461                                "length %llu\n",
462                                (unsigned long long)
463                                btrfs_dev_extent_chunk_tree(l, dev_extent),
464                                (unsigned long long)
465                                btrfs_dev_extent_chunk_objectid(l, dev_extent),
466                                (unsigned long long)
467                                btrfs_dev_extent_chunk_offset(l, dev_extent),
468                                (unsigned long long)
469                                btrfs_dev_extent_length(l, dev_extent));
470                         break;
471                 case BTRFS_STRING_ITEM_KEY:
472                         /* dirty, but it's simple */
473                         str = l->data + btrfs_item_ptr_offset(l, i);
474                         printf("\t\titem data %.*s\n", btrfs_item_size(l, item), str);
475                         break;
476                 };
477                 fflush(stdout);
478         }
479 }
480
481 void btrfs_print_tree(struct btrfs_root *root, struct extent_buffer *eb)
482 {
483         int i;
484         u32 nr;
485         u32 size;
486         struct btrfs_disk_key disk_key;
487         struct btrfs_key key;
488
489         if (!eb)
490                 return;
491         nr = btrfs_header_nritems(eb);
492         if (btrfs_is_leaf(eb)) {
493                 btrfs_print_leaf(root, eb);
494                 return;
495         }
496         printf("node %llu level %d items %d free %u generation %llu owner %llu\n",
497                (unsigned long long)eb->start,
498                 btrfs_header_level(eb), nr,
499                 (u32)BTRFS_NODEPTRS_PER_BLOCK(root) - nr,
500                 (unsigned long long)btrfs_header_generation(eb),
501                 (unsigned long long)btrfs_header_owner(eb));
502         print_uuids(eb);
503         fflush(stdout);
504         size = btrfs_level_size(root, btrfs_header_level(eb) - 1);
505         for (i = 0; i < nr; i++) {
506                 u64 blocknr = btrfs_node_blockptr(eb, i);
507                 btrfs_node_key(eb, &disk_key, i);
508                 btrfs_disk_key_to_cpu(&key, &disk_key);
509                 printf("\t");
510                 btrfs_print_key(&disk_key);
511                 printf(" block %llu (%llu) gen %llu\n",
512                        (unsigned long long)blocknr,
513                        (unsigned long long)blocknr / size,
514                        (unsigned long long)btrfs_node_ptr_generation(eb, i));
515                 fflush(stdout);
516         }
517         for (i = 0; i < nr; i++) {
518                 struct extent_buffer *next = read_tree_block(root,
519                                              btrfs_node_blockptr(eb, i),
520                                              size,
521                                              btrfs_node_ptr_generation(eb, i));
522                 if (!next) {
523                         fprintf(stderr, "failed to read %llu in tree %llu\n",
524                                 (unsigned long long)btrfs_node_blockptr(eb, i),
525                                 (unsigned long long)btrfs_header_owner(eb));
526                         continue;
527                 }
528                 if (btrfs_is_leaf(next) &&
529                     btrfs_header_level(eb) != 1)
530                         BUG();
531                 if (btrfs_header_level(next) !=
532                         btrfs_header_level(eb) - 1)
533                         BUG();
534                 btrfs_print_tree(root, next);
535                 free_extent_buffer(next);
536         }
537 }
538