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