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, nr;
 162        struct btrfs_item *item;
 163        struct btrfs_root_item *ri;
 164        struct btrfs_dir_item *di;
 165        struct btrfs_inode_item *ii;
 166        struct btrfs_block_group_item *bi;
 167        struct btrfs_file_extent_item *fi;
 168        struct btrfs_extent_data_ref *dref;
 169        struct btrfs_shared_data_ref *sref;
 170        struct btrfs_dev_extent *dev_extent;
 171        struct btrfs_key key;
 172        struct btrfs_key found_key;
 173
 174        if (!l)
 175                return;
 176
 177        nr = btrfs_header_nritems(l);
 178
 179        printk(KERN_INFO "leaf %llu total ptrs %d free space %d\n",
 180                (unsigned long long)btrfs_header_bytenr(l), nr,
 181                btrfs_leaf_free_space(root, l));
 182        for (i = 0 ; i < nr ; i++) {
 183                item = btrfs_item_nr(l, i);
 184                btrfs_item_key_to_cpu(l, &key, i);
 185                type = btrfs_key_type(&key);
 186                printk(KERN_INFO "\titem %d key (%llu %x %llu) itemoff %d "
 187                       "itemsize %d\n",
 188                        i,
 189                        (unsigned long long)key.objectid, type,
 190                        (unsigned long long)key.offset,
 191                        btrfs_item_offset(l, item), btrfs_item_size(l, item));
 192                switch (type) {
 193                case BTRFS_INODE_ITEM_KEY:
 194                        ii = btrfs_item_ptr(l, i, struct btrfs_inode_item);
 195                        printk(KERN_INFO "\t\tinode generation %llu size %llu "
 196                               "mode %o\n",
 197                               (unsigned long long)
 198                               btrfs_inode_generation(l, ii),
 199                              (unsigned long long)btrfs_inode_size(l, ii),
 200                               btrfs_inode_mode(l, ii));
 201                        break;
 202                case BTRFS_DIR_ITEM_KEY:
 203                        di = btrfs_item_ptr(l, i, struct btrfs_dir_item);
 204                        btrfs_dir_item_key_to_cpu(l, di, &found_key);
 205                        printk(KERN_INFO "\t\tdir oid %llu type %u\n",
 206                                (unsigned long long)found_key.objectid,
 207                                btrfs_dir_type(l, di));
 208                        break;
 209                case BTRFS_ROOT_ITEM_KEY:
 210                        ri = btrfs_item_ptr(l, i, struct btrfs_root_item);
 211                        printk(KERN_INFO "\t\troot data bytenr %llu refs %u\n",
 212                                (unsigned long long)
 213                                btrfs_disk_root_bytenr(l, ri),
 214                                btrfs_disk_root_refs(l, ri));
 215                        break;
 216                case BTRFS_EXTENT_ITEM_KEY:
 217                        print_extent_item(l, i);
 218                        break;
 219                case BTRFS_TREE_BLOCK_REF_KEY:
 220                        printk(KERN_INFO "\t\ttree block backref\n");
 221                        break;
 222                case BTRFS_SHARED_BLOCK_REF_KEY:
 223                        printk(KERN_INFO "\t\tshared block backref\n");
 224                        break;
 225                case BTRFS_EXTENT_DATA_REF_KEY:
 226                        dref = btrfs_item_ptr(l, i,
 227                                              struct btrfs_extent_data_ref);
 228                        print_extent_data_ref(l, dref);
 229                        break;
 230                case BTRFS_SHARED_DATA_REF_KEY:
 231                        sref = btrfs_item_ptr(l, i,
 232                                              struct btrfs_shared_data_ref);
 233                        printk(KERN_INFO "\t\tshared data backref count %u\n",
 234                               btrfs_shared_data_ref_count(l, sref));
 235                        break;
 236                case BTRFS_EXTENT_DATA_KEY:
 237                        fi = btrfs_item_ptr(l, i,
 238                                            struct btrfs_file_extent_item);
 239                        if (btrfs_file_extent_type(l, fi) ==
 240                            BTRFS_FILE_EXTENT_INLINE) {
 241                                printk(KERN_INFO "\t\tinline extent data "
 242                                       "size %u\n",
 243                                       btrfs_file_extent_inline_len(l, fi));
 244                                break;
 245                        }
 246                        printk(KERN_INFO "\t\textent data disk bytenr %llu "
 247                               "nr %llu\n",
 248                               (unsigned long long)
 249                               btrfs_file_extent_disk_bytenr(l, fi),
 250                               (unsigned long long)
 251                               btrfs_file_extent_disk_num_bytes(l, fi));
 252                        printk(KERN_INFO "\t\textent data offset %llu "
 253                               "nr %llu ram %llu\n",
 254                               (unsigned long long)
 255                               btrfs_file_extent_offset(l, fi),
 256                               (unsigned long long)
 257                               btrfs_file_extent_num_bytes(l, fi),
 258                               (unsigned long long)
 259                               btrfs_file_extent_ram_bytes(l, fi));
 260                        break;
 261                case BTRFS_EXTENT_REF_V0_KEY:
 262#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
 263                        print_extent_ref_v0(l, i);
 264#else
 265                        BUG();
 266#endif
 267                        break;
 268                case BTRFS_BLOCK_GROUP_ITEM_KEY:
 269                        bi = btrfs_item_ptr(l, i,
 270                                            struct btrfs_block_group_item);
 271                        printk(KERN_INFO "\t\tblock group used %llu\n",
 272                               (unsigned long long)
 273                               btrfs_disk_block_group_used(l, bi));
 274                        break;
 275                case BTRFS_CHUNK_ITEM_KEY:
 276                        print_chunk(l, btrfs_item_ptr(l, i,
 277                                                      struct btrfs_chunk));
 278                        break;
 279                case BTRFS_DEV_ITEM_KEY:
 280                        print_dev_item(l, btrfs_item_ptr(l, i,
 281                                        struct btrfs_dev_item));
 282                        break;
 283                case BTRFS_DEV_EXTENT_KEY:
 284                        dev_extent = btrfs_item_ptr(l, i,
 285                                                    struct btrfs_dev_extent);
 286                        printk(KERN_INFO "\t\tdev extent chunk_tree %llu\n"
 287                               "\t\tchunk objectid %llu chunk offset %llu "
 288                               "length %llu\n",
 289                               (unsigned long long)
 290                               btrfs_dev_extent_chunk_tree(l, dev_extent),
 291                               (unsigned long long)
 292                               btrfs_dev_extent_chunk_objectid(l, dev_extent),
 293                               (unsigned long long)
 294                               btrfs_dev_extent_chunk_offset(l, dev_extent),
 295                               (unsigned long long)
 296                               btrfs_dev_extent_length(l, dev_extent));
 297                };
 298        }
 299}
 300
 301void btrfs_print_tree(struct btrfs_root *root, struct extent_buffer *c)
 302{
 303        int i; u32 nr;
 304        struct btrfs_key key;
 305        int level;
 306
 307        if (!c)
 308                return;
 309        nr = btrfs_header_nritems(c);
 310        level = btrfs_header_level(c);
 311        if (level == 0) {
 312                btrfs_print_leaf(root, c);
 313                return;
 314        }
 315        printk(KERN_INFO "node %llu level %d total ptrs %d free spc %u\n",
 316               (unsigned long long)btrfs_header_bytenr(c),
 317              level, nr,
 318               (u32)BTRFS_NODEPTRS_PER_BLOCK(root) - nr);
 319        for (i = 0; i < nr; i++) {
 320                btrfs_node_key_to_cpu(c, &key, i);
 321                printk(KERN_INFO "\tkey %d (%llu %u %llu) block %llu\n",
 322                       i,
 323                       (unsigned long long)key.objectid,
 324                       key.type,
 325                       (unsigned long long)key.offset,
 326                       (unsigned long long)btrfs_node_blockptr(c, i));
 327        }
 328        for (i = 0; i < nr; i++) {
 329                struct extent_buffer *next = read_tree_block(root,
 330                                        btrfs_node_blockptr(c, i),
 331                                        btrfs_level_size(root, level - 1),
 332                                        btrfs_node_ptr_generation(c, i));
 333                if (btrfs_is_leaf(next) &&
 334                   level != 1)
 335                        BUG();
 336                if (btrfs_header_level(next) !=
 337                       level - 1)
 338                        BUG();
 339                btrfs_print_tree(root, next);
 340                free_extent_buffer(next);
 341        }
 342}
 343