linux/fs/btrfs/print-tree.c
<<
>>
Prefs
   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 "ctree.h"
  20#include "disk-io.h"
  21#include "print-tree.h"
  22
  23static void print_chunk(struct extent_buffer *eb, struct btrfs_chunk *chunk)
  24{
  25        int num_stripes = btrfs_chunk_num_stripes(eb, chunk);
  26        int i;
  27        printk(KERN_INFO "\t\tchunk length %llu owner %llu type %llu "
  28               "num_stripes %d\n",
  29               (unsigned long long)btrfs_chunk_length(eb, chunk),
  30               (unsigned long long)btrfs_chunk_owner(eb, chunk),
  31               (unsigned long long)btrfs_chunk_type(eb, chunk),
  32               num_stripes);
  33        for (i = 0 ; i < num_stripes ; i++) {
  34                printk(KERN_INFO "\t\t\tstripe %d devid %llu offset %llu\n", i,
  35                      (unsigned long long)btrfs_stripe_devid_nr(eb, chunk, i),
  36                      (unsigned long long)btrfs_stripe_offset_nr(eb, chunk, i));
  37        }
  38}
  39static void print_dev_item(struct extent_buffer *eb,
  40                           struct btrfs_dev_item *dev_item)
  41{
  42        printk(KERN_INFO "\t\tdev item devid %llu "
  43               "total_bytes %llu bytes used %llu\n",
  44               (unsigned long long)btrfs_device_id(eb, dev_item),
  45               (unsigned long long)btrfs_device_total_bytes(eb, dev_item),
  46               (unsigned long long)btrfs_device_bytes_used(eb, dev_item));
  47}
  48static void print_extent_data_ref(struct extent_buffer *eb,
  49                                  struct btrfs_extent_data_ref *ref)
  50{
  51        printk(KERN_INFO "\t\textent data backref root %llu "
  52               "objectid %llu offset %llu count %u\n",
  53               (unsigned long long)btrfs_extent_data_ref_root(eb, ref),
  54               (unsigned long long)btrfs_extent_data_ref_objectid(eb, ref),
  55               (unsigned long long)btrfs_extent_data_ref_offset(eb, ref),
  56               btrfs_extent_data_ref_count(eb, ref));
  57}
  58
  59static void print_extent_item(struct extent_buffer *eb, int slot)
  60{
  61        struct btrfs_extent_item *ei;
  62        struct btrfs_extent_inline_ref *iref;
  63        struct btrfs_extent_data_ref *dref;
  64        struct btrfs_shared_data_ref *sref;
  65        struct btrfs_disk_key key;
  66        unsigned long end;
  67        unsigned long ptr;
  68        int type;
  69        u32 item_size = btrfs_item_size_nr(eb, slot);
  70        u64 flags;
  71        u64 offset;
  72
  73        if (item_size < sizeof(*ei)) {
  74#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
  75                struct btrfs_extent_item_v0 *ei0;
  76                BUG_ON(item_size != sizeof(*ei0));
  77                ei0 = btrfs_item_ptr(eb, slot, struct btrfs_extent_item_v0);
  78                printk(KERN_INFO "\t\textent refs %u\n",
  79                       btrfs_extent_refs_v0(eb, ei0));
  80                return;
  81#else
  82                BUG();
  83#endif
  84        }
  85
  86        ei = btrfs_item_ptr(eb, slot, struct btrfs_extent_item);
  87        flags = btrfs_extent_flags(eb, ei);
  88
  89        printk(KERN_INFO "\t\textent refs %llu gen %llu flags %llu\n",
  90               (unsigned long long)btrfs_extent_refs(eb, ei),
  91               (unsigned long long)btrfs_extent_generation(eb, ei),
  92               (unsigned long long)flags);
  93
  94        if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
  95                struct btrfs_tree_block_info *info;
  96                info = (struct btrfs_tree_block_info *)(ei + 1);
  97                btrfs_tree_block_key(eb, info, &key);
  98                printk(KERN_INFO "\t\ttree block key (%llu %x %llu) "
  99                       "level %d\n",
 100                       (unsigned long long)btrfs_disk_key_objectid(&key),
 101                       key.type,
 102                       (unsigned long long)btrfs_disk_key_offset(&key),
 103                       btrfs_tree_block_level(eb, info));
 104                iref = (struct btrfs_extent_inline_ref *)(info + 1);
 105        } else {
 106                iref = (struct btrfs_extent_inline_ref *)(ei + 1);
 107        }
 108
 109        ptr = (unsigned long)iref;
 110        end = (unsigned long)ei + item_size;
 111        while (ptr < end) {
 112                iref = (struct btrfs_extent_inline_ref *)ptr;
 113                type = btrfs_extent_inline_ref_type(eb, iref);
 114                offset = btrfs_extent_inline_ref_offset(eb, iref);
 115                switch (type) {
 116                case BTRFS_TREE_BLOCK_REF_KEY:
 117                        printk(KERN_INFO "\t\ttree block backref "
 118                                "root %llu\n", (unsigned long long)offset);
 119                        break;
 120                case BTRFS_SHARED_BLOCK_REF_KEY:
 121                        printk(KERN_INFO "\t\tshared block backref "
 122                                "parent %llu\n", (unsigned long long)offset);
 123                        break;
 124                case BTRFS_EXTENT_DATA_REF_KEY:
 125                        dref = (struct btrfs_extent_data_ref *)(&iref->offset);
 126                        print_extent_data_ref(eb, dref);
 127                        break;
 128                case BTRFS_SHARED_DATA_REF_KEY:
 129                        sref = (struct btrfs_shared_data_ref *)(iref + 1);
 130                        printk(KERN_INFO "\t\tshared data backref "
 131                               "parent %llu count %u\n",
 132                               (unsigned long long)offset,
 133                               btrfs_shared_data_ref_count(eb, sref));
 134                        break;
 135                default:
 136                        BUG();
 137                }
 138                ptr += btrfs_extent_inline_ref_size(type);
 139        }
 140        WARN_ON(ptr > end);
 141}
 142
 143#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
 144static void print_extent_ref_v0(struct extent_buffer *eb, int slot)
 145{
 146        struct btrfs_extent_ref_v0 *ref0;
 147
 148        ref0 = btrfs_item_ptr(eb, slot, struct btrfs_extent_ref_v0);
 149        printk("\t\textent back ref root %llu gen %llu "
 150                "owner %llu num_refs %lu\n",
 151                (unsigned long long)btrfs_ref_root_v0(eb, ref0),
 152                (unsigned long long)btrfs_ref_generation_v0(eb, ref0),
 153                (unsigned long long)btrfs_ref_objectid_v0(eb, ref0),
 154                (unsigned long)btrfs_ref_count_v0(eb, ref0));
 155}
 156#endif
 157
 158void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
 159{
 160        int i;
 161        u32 type;
 162        u32 nr = btrfs_header_nritems(l);
 163        struct btrfs_item *item;
 164        struct btrfs_root_item *ri;
 165        struct btrfs_dir_item *di;
 166        struct btrfs_inode_item *ii;
 167        struct btrfs_block_group_item *bi;
 168        struct btrfs_file_extent_item *fi;
 169        struct btrfs_extent_data_ref *dref;
 170        struct btrfs_shared_data_ref *sref;
 171        struct btrfs_dev_extent *dev_extent;
 172        struct btrfs_key key;
 173        struct btrfs_key found_key;
 174
 175        printk(KERN_INFO "leaf %llu total ptrs %d free space %d\n",
 176                (unsigned long long)btrfs_header_bytenr(l), nr,
 177                btrfs_leaf_free_space(root, l));
 178        for (i = 0 ; i < nr ; i++) {
 179                item = btrfs_item_nr(l, i);
 180                btrfs_item_key_to_cpu(l, &key, i);
 181                type = btrfs_key_type(&key);
 182                printk(KERN_INFO "\titem %d key (%llu %x %llu) itemoff %d "
 183                       "itemsize %d\n",
 184                        i,
 185                        (unsigned long long)key.objectid, type,
 186                        (unsigned long long)key.offset,
 187                        btrfs_item_offset(l, item), btrfs_item_size(l, item));
 188                switch (type) {
 189                case BTRFS_INODE_ITEM_KEY:
 190                        ii = btrfs_item_ptr(l, i, struct btrfs_inode_item);
 191                        printk(KERN_INFO "\t\tinode generation %llu size %llu "
 192                               "mode %o\n",
 193                               (unsigned long long)
 194                               btrfs_inode_generation(l, ii),
 195                              (unsigned long long)btrfs_inode_size(l, ii),
 196                               btrfs_inode_mode(l, ii));
 197                        break;
 198                case BTRFS_DIR_ITEM_KEY:
 199                        di = btrfs_item_ptr(l, i, struct btrfs_dir_item);
 200                        btrfs_dir_item_key_to_cpu(l, di, &found_key);
 201                        printk(KERN_INFO "\t\tdir oid %llu type %u\n",
 202                                (unsigned long long)found_key.objectid,
 203                                btrfs_dir_type(l, di));
 204                        break;
 205                case BTRFS_ROOT_ITEM_KEY:
 206                        ri = btrfs_item_ptr(l, i, struct btrfs_root_item);
 207                        printk(KERN_INFO "\t\troot data bytenr %llu refs %u\n",
 208                                (unsigned long long)
 209                                btrfs_disk_root_bytenr(l, ri),
 210                                btrfs_disk_root_refs(l, ri));
 211                        break;
 212                case BTRFS_EXTENT_ITEM_KEY:
 213                        print_extent_item(l, i);
 214                        break;
 215                case BTRFS_TREE_BLOCK_REF_KEY:
 216                        printk(KERN_INFO "\t\ttree block backref\n");
 217                        break;
 218                case BTRFS_SHARED_BLOCK_REF_KEY:
 219                        printk(KERN_INFO "\t\tshared block backref\n");
 220                        break;
 221                case BTRFS_EXTENT_DATA_REF_KEY:
 222                        dref = btrfs_item_ptr(l, i,
 223                                              struct btrfs_extent_data_ref);
 224                        print_extent_data_ref(l, dref);
 225                        break;
 226                case BTRFS_SHARED_DATA_REF_KEY:
 227                        sref = btrfs_item_ptr(l, i,
 228                                              struct btrfs_shared_data_ref);
 229                        printk(KERN_INFO "\t\tshared data backref count %u\n",
 230                               btrfs_shared_data_ref_count(l, sref));
 231                        break;
 232                case BTRFS_EXTENT_DATA_KEY:
 233                        fi = btrfs_item_ptr(l, i,
 234                                            struct btrfs_file_extent_item);
 235                        if (btrfs_file_extent_type(l, fi) ==
 236                            BTRFS_FILE_EXTENT_INLINE) {
 237                                printk(KERN_INFO "\t\tinline extent data "
 238                                       "size %u\n",
 239                                       btrfs_file_extent_inline_len(l, fi));
 240                                break;
 241                        }
 242                        printk(KERN_INFO "\t\textent data disk bytenr %llu "
 243                               "nr %llu\n",
 244                               (unsigned long long)
 245                               btrfs_file_extent_disk_bytenr(l, fi),
 246                               (unsigned long long)
 247                               btrfs_file_extent_disk_num_bytes(l, fi));
 248                        printk(KERN_INFO "\t\textent data offset %llu "
 249                               "nr %llu ram %llu\n",
 250                               (unsigned long long)
 251                               btrfs_file_extent_offset(l, fi),
 252                               (unsigned long long)
 253                               btrfs_file_extent_num_bytes(l, fi),
 254                               (unsigned long long)
 255                               btrfs_file_extent_ram_bytes(l, fi));
 256                        break;
 257                case BTRFS_EXTENT_REF_V0_KEY:
 258#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
 259                        print_extent_ref_v0(l, i);
 260#else
 261                        BUG();
 262#endif
 263                case BTRFS_BLOCK_GROUP_ITEM_KEY:
 264                        bi = btrfs_item_ptr(l, i,
 265                                            struct btrfs_block_group_item);
 266                        printk(KERN_INFO "\t\tblock group used %llu\n",
 267                               (unsigned long long)
 268                               btrfs_disk_block_group_used(l, bi));
 269                        break;
 270                case BTRFS_CHUNK_ITEM_KEY:
 271                        print_chunk(l, btrfs_item_ptr(l, i,
 272                                                      struct btrfs_chunk));
 273                        break;
 274                case BTRFS_DEV_ITEM_KEY:
 275                        print_dev_item(l, btrfs_item_ptr(l, i,
 276                                        struct btrfs_dev_item));
 277                        break;
 278                case BTRFS_DEV_EXTENT_KEY:
 279                        dev_extent = btrfs_item_ptr(l, i,
 280                                                    struct btrfs_dev_extent);
 281                        printk(KERN_INFO "\t\tdev extent chunk_tree %llu\n"
 282                               "\t\tchunk objectid %llu chunk offset %llu "
 283                               "length %llu\n",
 284                               (unsigned long long)
 285                               btrfs_dev_extent_chunk_tree(l, dev_extent),
 286                               (unsigned long long)
 287                               btrfs_dev_extent_chunk_objectid(l, dev_extent),
 288                               (unsigned long long)
 289                               btrfs_dev_extent_chunk_offset(l, dev_extent),
 290                               (unsigned long long)
 291                               btrfs_dev_extent_length(l, dev_extent));
 292                };
 293        }
 294}
 295
 296void btrfs_print_tree(struct btrfs_root *root, struct extent_buffer *c)
 297{
 298        int i; u32 nr;
 299        struct btrfs_key key;
 300        int level;
 301
 302        if (!c)
 303                return;
 304        nr = btrfs_header_nritems(c);
 305        level = btrfs_header_level(c);
 306        if (level == 0) {
 307                btrfs_print_leaf(root, c);
 308                return;
 309        }
 310        printk(KERN_INFO "node %llu level %d total ptrs %d free spc %u\n",
 311               (unsigned long long)btrfs_header_bytenr(c),
 312              level, nr,
 313               (u32)BTRFS_NODEPTRS_PER_BLOCK(root) - nr);
 314        for (i = 0; i < nr; i++) {
 315                btrfs_node_key_to_cpu(c, &key, i);
 316                printk(KERN_INFO "\tkey %d (%llu %u %llu) block %llu\n",
 317                       i,
 318                       (unsigned long long)key.objectid,
 319                       key.type,
 320                       (unsigned long long)key.offset,
 321                       (unsigned long long)btrfs_node_blockptr(c, i));
 322        }
 323        for (i = 0; i < nr; i++) {
 324                struct extent_buffer *next = read_tree_block(root,
 325                                        btrfs_node_blockptr(c, i),
 326                                        btrfs_level_size(root, level - 1),
 327                                        btrfs_node_ptr_generation(c, i));
 328                if (btrfs_is_leaf(next) &&
 329                   level != 1)
 330                        BUG();
 331                if (btrfs_header_level(next) !=
 332                       level - 1)
 333                        BUG();
 334                btrfs_print_tree(root, next);
 335                free_extent_buffer(next);
 336        }
 337}
 338