root/fs/btrfs/print-tree.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. print_chunk
  2. print_dev_item
  3. print_extent_data_ref
  4. print_extent_item
  5. print_uuid_item
  6. print_eb_refs_lock
  7. btrfs_print_leaf
  8. btrfs_print_tree

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright (C) 2007 Oracle.  All rights reserved.
   4  */
   5 
   6 #include "ctree.h"
   7 #include "disk-io.h"
   8 #include "print-tree.h"
   9 
  10 static void print_chunk(struct extent_buffer *eb, struct btrfs_chunk *chunk)
  11 {
  12         int num_stripes = btrfs_chunk_num_stripes(eb, chunk);
  13         int i;
  14         pr_info("\t\tchunk length %llu owner %llu type %llu num_stripes %d\n",
  15                btrfs_chunk_length(eb, chunk), btrfs_chunk_owner(eb, chunk),
  16                btrfs_chunk_type(eb, chunk), num_stripes);
  17         for (i = 0 ; i < num_stripes ; i++) {
  18                 pr_info("\t\t\tstripe %d devid %llu offset %llu\n", i,
  19                       btrfs_stripe_devid_nr(eb, chunk, i),
  20                       btrfs_stripe_offset_nr(eb, chunk, i));
  21         }
  22 }
  23 static void print_dev_item(struct extent_buffer *eb,
  24                            struct btrfs_dev_item *dev_item)
  25 {
  26         pr_info("\t\tdev item devid %llu total_bytes %llu bytes used %llu\n",
  27                btrfs_device_id(eb, dev_item),
  28                btrfs_device_total_bytes(eb, dev_item),
  29                btrfs_device_bytes_used(eb, dev_item));
  30 }
  31 static void print_extent_data_ref(struct extent_buffer *eb,
  32                                   struct btrfs_extent_data_ref *ref)
  33 {
  34         pr_cont("extent data backref root %llu objectid %llu offset %llu count %u\n",
  35                btrfs_extent_data_ref_root(eb, ref),
  36                btrfs_extent_data_ref_objectid(eb, ref),
  37                btrfs_extent_data_ref_offset(eb, ref),
  38                btrfs_extent_data_ref_count(eb, ref));
  39 }
  40 
  41 static void print_extent_item(struct extent_buffer *eb, int slot, int type)
  42 {
  43         struct btrfs_extent_item *ei;
  44         struct btrfs_extent_inline_ref *iref;
  45         struct btrfs_extent_data_ref *dref;
  46         struct btrfs_shared_data_ref *sref;
  47         struct btrfs_disk_key key;
  48         unsigned long end;
  49         unsigned long ptr;
  50         u32 item_size = btrfs_item_size_nr(eb, slot);
  51         u64 flags;
  52         u64 offset;
  53         int ref_index = 0;
  54 
  55         if (unlikely(item_size < sizeof(*ei))) {
  56                 btrfs_print_v0_err(eb->fs_info);
  57                 btrfs_handle_fs_error(eb->fs_info, -EINVAL, NULL);
  58         }
  59 
  60         ei = btrfs_item_ptr(eb, slot, struct btrfs_extent_item);
  61         flags = btrfs_extent_flags(eb, ei);
  62 
  63         pr_info("\t\textent refs %llu gen %llu flags %llu\n",
  64                btrfs_extent_refs(eb, ei), btrfs_extent_generation(eb, ei),
  65                flags);
  66 
  67         if ((type == BTRFS_EXTENT_ITEM_KEY) &&
  68             flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
  69                 struct btrfs_tree_block_info *info;
  70                 info = (struct btrfs_tree_block_info *)(ei + 1);
  71                 btrfs_tree_block_key(eb, info, &key);
  72                 pr_info("\t\ttree block key (%llu %u %llu) level %d\n",
  73                        btrfs_disk_key_objectid(&key), key.type,
  74                        btrfs_disk_key_offset(&key),
  75                        btrfs_tree_block_level(eb, info));
  76                 iref = (struct btrfs_extent_inline_ref *)(info + 1);
  77         } else {
  78                 iref = (struct btrfs_extent_inline_ref *)(ei + 1);
  79         }
  80 
  81         ptr = (unsigned long)iref;
  82         end = (unsigned long)ei + item_size;
  83         while (ptr < end) {
  84                 iref = (struct btrfs_extent_inline_ref *)ptr;
  85                 type = btrfs_extent_inline_ref_type(eb, iref);
  86                 offset = btrfs_extent_inline_ref_offset(eb, iref);
  87                 pr_info("\t\tref#%d: ", ref_index++);
  88                 switch (type) {
  89                 case BTRFS_TREE_BLOCK_REF_KEY:
  90                         pr_cont("tree block backref root %llu\n", offset);
  91                         break;
  92                 case BTRFS_SHARED_BLOCK_REF_KEY:
  93                         pr_cont("shared block backref parent %llu\n", offset);
  94                         /*
  95                          * offset is supposed to be a tree block which
  96                          * must be aligned to nodesize.
  97                          */
  98                         if (!IS_ALIGNED(offset, eb->fs_info->nodesize))
  99                                 pr_info("\t\t\t(parent %llu is NOT ALIGNED to nodesize %llu)\n",
 100                                         offset, (unsigned long long)eb->fs_info->nodesize);
 101                         break;
 102                 case BTRFS_EXTENT_DATA_REF_KEY:
 103                         dref = (struct btrfs_extent_data_ref *)(&iref->offset);
 104                         print_extent_data_ref(eb, dref);
 105                         break;
 106                 case BTRFS_SHARED_DATA_REF_KEY:
 107                         sref = (struct btrfs_shared_data_ref *)(iref + 1);
 108                         pr_cont("shared data backref parent %llu count %u\n",
 109                                offset, btrfs_shared_data_ref_count(eb, sref));
 110                         /*
 111                          * offset is supposed to be a tree block which
 112                          * must be aligned to nodesize.
 113                          */
 114                         if (!IS_ALIGNED(offset, eb->fs_info->nodesize))
 115                                 pr_info("\t\t\t(parent %llu is NOT ALIGNED to nodesize %llu)\n",
 116                                      offset, (unsigned long long)eb->fs_info->nodesize);
 117                         break;
 118                 default:
 119                         pr_cont("(extent %llu has INVALID ref type %d)\n",
 120                                   eb->start, type);
 121                         return;
 122                 }
 123                 ptr += btrfs_extent_inline_ref_size(type);
 124         }
 125         WARN_ON(ptr > end);
 126 }
 127 
 128 static void print_uuid_item(struct extent_buffer *l, unsigned long offset,
 129                             u32 item_size)
 130 {
 131         if (!IS_ALIGNED(item_size, sizeof(u64))) {
 132                 pr_warn("BTRFS: uuid item with illegal size %lu!\n",
 133                         (unsigned long)item_size);
 134                 return;
 135         }
 136         while (item_size) {
 137                 __le64 subvol_id;
 138 
 139                 read_extent_buffer(l, &subvol_id, offset, sizeof(subvol_id));
 140                 pr_info("\t\tsubvol_id %llu\n",
 141                        (unsigned long long)le64_to_cpu(subvol_id));
 142                 item_size -= sizeof(u64);
 143                 offset += sizeof(u64);
 144         }
 145 }
 146 
 147 /*
 148  * Helper to output refs and locking status of extent buffer.  Useful to debug
 149  * race condition related problems.
 150  */
 151 static void print_eb_refs_lock(struct extent_buffer *eb)
 152 {
 153 #ifdef CONFIG_BTRFS_DEBUG
 154         btrfs_info(eb->fs_info,
 155 "refs %u lock (w:%d r:%d bw:%d br:%d sw:%d sr:%d) lock_owner %u current %u",
 156                    atomic_read(&eb->refs), eb->write_locks,
 157                    atomic_read(&eb->read_locks),
 158                    eb->blocking_writers,
 159                    atomic_read(&eb->blocking_readers),
 160                    eb->spinning_writers,
 161                    atomic_read(&eb->spinning_readers),
 162                    eb->lock_owner, current->pid);
 163 #endif
 164 }
 165 
 166 void btrfs_print_leaf(struct extent_buffer *l)
 167 {
 168         struct btrfs_fs_info *fs_info;
 169         int i;
 170         u32 type, nr;
 171         struct btrfs_item *item;
 172         struct btrfs_root_item *ri;
 173         struct btrfs_dir_item *di;
 174         struct btrfs_inode_item *ii;
 175         struct btrfs_block_group_item *bi;
 176         struct btrfs_file_extent_item *fi;
 177         struct btrfs_extent_data_ref *dref;
 178         struct btrfs_shared_data_ref *sref;
 179         struct btrfs_dev_extent *dev_extent;
 180         struct btrfs_key key;
 181         struct btrfs_key found_key;
 182 
 183         if (!l)
 184                 return;
 185 
 186         fs_info = l->fs_info;
 187         nr = btrfs_header_nritems(l);
 188 
 189         btrfs_info(fs_info,
 190                    "leaf %llu gen %llu total ptrs %d free space %d owner %llu",
 191                    btrfs_header_bytenr(l), btrfs_header_generation(l), nr,
 192                    btrfs_leaf_free_space(l), btrfs_header_owner(l));
 193         print_eb_refs_lock(l);
 194         for (i = 0 ; i < nr ; i++) {
 195                 item = btrfs_item_nr(i);
 196                 btrfs_item_key_to_cpu(l, &key, i);
 197                 type = key.type;
 198                 pr_info("\titem %d key (%llu %u %llu) itemoff %d itemsize %d\n",
 199                         i, key.objectid, type, key.offset,
 200                         btrfs_item_offset(l, item), btrfs_item_size(l, item));
 201                 switch (type) {
 202                 case BTRFS_INODE_ITEM_KEY:
 203                         ii = btrfs_item_ptr(l, i, struct btrfs_inode_item);
 204                         pr_info("\t\tinode generation %llu size %llu mode %o\n",
 205                                btrfs_inode_generation(l, ii),
 206                                btrfs_inode_size(l, ii),
 207                                btrfs_inode_mode(l, ii));
 208                         break;
 209                 case BTRFS_DIR_ITEM_KEY:
 210                         di = btrfs_item_ptr(l, i, struct btrfs_dir_item);
 211                         btrfs_dir_item_key_to_cpu(l, di, &found_key);
 212                         pr_info("\t\tdir oid %llu type %u\n",
 213                                 found_key.objectid,
 214                                 btrfs_dir_type(l, di));
 215                         break;
 216                 case BTRFS_ROOT_ITEM_KEY:
 217                         ri = btrfs_item_ptr(l, i, struct btrfs_root_item);
 218                         pr_info("\t\troot data bytenr %llu refs %u\n",
 219                                 btrfs_disk_root_bytenr(l, ri),
 220                                 btrfs_disk_root_refs(l, ri));
 221                         break;
 222                 case BTRFS_EXTENT_ITEM_KEY:
 223                 case BTRFS_METADATA_ITEM_KEY:
 224                         print_extent_item(l, i, type);
 225                         break;
 226                 case BTRFS_TREE_BLOCK_REF_KEY:
 227                         pr_info("\t\ttree block backref\n");
 228                         break;
 229                 case BTRFS_SHARED_BLOCK_REF_KEY:
 230                         pr_info("\t\tshared block backref\n");
 231                         break;
 232                 case BTRFS_EXTENT_DATA_REF_KEY:
 233                         dref = btrfs_item_ptr(l, i,
 234                                               struct btrfs_extent_data_ref);
 235                         print_extent_data_ref(l, dref);
 236                         break;
 237                 case BTRFS_SHARED_DATA_REF_KEY:
 238                         sref = btrfs_item_ptr(l, i,
 239                                               struct btrfs_shared_data_ref);
 240                         pr_info("\t\tshared data backref count %u\n",
 241                                btrfs_shared_data_ref_count(l, sref));
 242                         break;
 243                 case BTRFS_EXTENT_DATA_KEY:
 244                         fi = btrfs_item_ptr(l, i,
 245                                             struct btrfs_file_extent_item);
 246                         if (btrfs_file_extent_type(l, fi) ==
 247                             BTRFS_FILE_EXTENT_INLINE) {
 248                                 pr_info("\t\tinline extent data size %llu\n",
 249                                        btrfs_file_extent_ram_bytes(l, fi));
 250                                 break;
 251                         }
 252                         pr_info("\t\textent data disk bytenr %llu nr %llu\n",
 253                                btrfs_file_extent_disk_bytenr(l, fi),
 254                                btrfs_file_extent_disk_num_bytes(l, fi));
 255                         pr_info("\t\textent data offset %llu nr %llu ram %llu\n",
 256                                btrfs_file_extent_offset(l, fi),
 257                                btrfs_file_extent_num_bytes(l, fi),
 258                                btrfs_file_extent_ram_bytes(l, fi));
 259                         break;
 260                 case BTRFS_EXTENT_REF_V0_KEY:
 261                         btrfs_print_v0_err(fs_info);
 262                         btrfs_handle_fs_error(fs_info, -EINVAL, NULL);
 263                         break;
 264                 case BTRFS_BLOCK_GROUP_ITEM_KEY:
 265                         bi = btrfs_item_ptr(l, i,
 266                                             struct btrfs_block_group_item);
 267                         pr_info(
 268                    "\t\tblock group used %llu chunk_objectid %llu flags %llu\n",
 269                                 btrfs_disk_block_group_used(l, bi),
 270                                 btrfs_disk_block_group_chunk_objectid(l, bi),
 271                                 btrfs_disk_block_group_flags(l, bi));
 272                         break;
 273                 case BTRFS_CHUNK_ITEM_KEY:
 274                         print_chunk(l, btrfs_item_ptr(l, i,
 275                                                       struct btrfs_chunk));
 276                         break;
 277                 case BTRFS_DEV_ITEM_KEY:
 278                         print_dev_item(l, btrfs_item_ptr(l, i,
 279                                         struct btrfs_dev_item));
 280                         break;
 281                 case BTRFS_DEV_EXTENT_KEY:
 282                         dev_extent = btrfs_item_ptr(l, i,
 283                                                     struct btrfs_dev_extent);
 284                         pr_info("\t\tdev extent chunk_tree %llu\n\t\tchunk objectid %llu chunk offset %llu length %llu\n",
 285                                btrfs_dev_extent_chunk_tree(l, dev_extent),
 286                                btrfs_dev_extent_chunk_objectid(l, dev_extent),
 287                                btrfs_dev_extent_chunk_offset(l, dev_extent),
 288                                btrfs_dev_extent_length(l, dev_extent));
 289                         break;
 290                 case BTRFS_PERSISTENT_ITEM_KEY:
 291                         pr_info("\t\tpersistent item objectid %llu offset %llu\n",
 292                                         key.objectid, key.offset);
 293                         switch (key.objectid) {
 294                         case BTRFS_DEV_STATS_OBJECTID:
 295                                 pr_info("\t\tdevice stats\n");
 296                                 break;
 297                         default:
 298                                 pr_info("\t\tunknown persistent item\n");
 299                         }
 300                         break;
 301                 case BTRFS_TEMPORARY_ITEM_KEY:
 302                         pr_info("\t\ttemporary item objectid %llu offset %llu\n",
 303                                         key.objectid, key.offset);
 304                         switch (key.objectid) {
 305                         case BTRFS_BALANCE_OBJECTID:
 306                                 pr_info("\t\tbalance status\n");
 307                                 break;
 308                         default:
 309                                 pr_info("\t\tunknown temporary item\n");
 310                         }
 311                         break;
 312                 case BTRFS_DEV_REPLACE_KEY:
 313                         pr_info("\t\tdev replace\n");
 314                         break;
 315                 case BTRFS_UUID_KEY_SUBVOL:
 316                 case BTRFS_UUID_KEY_RECEIVED_SUBVOL:
 317                         print_uuid_item(l, btrfs_item_ptr_offset(l, i),
 318                                         btrfs_item_size_nr(l, i));
 319                         break;
 320                 };
 321         }
 322 }
 323 
 324 void btrfs_print_tree(struct extent_buffer *c, bool follow)
 325 {
 326         struct btrfs_fs_info *fs_info;
 327         int i; u32 nr;
 328         struct btrfs_key key;
 329         int level;
 330 
 331         if (!c)
 332                 return;
 333         fs_info = c->fs_info;
 334         nr = btrfs_header_nritems(c);
 335         level = btrfs_header_level(c);
 336         if (level == 0) {
 337                 btrfs_print_leaf(c);
 338                 return;
 339         }
 340         btrfs_info(fs_info,
 341                    "node %llu level %d gen %llu total ptrs %d free spc %u owner %llu",
 342                    btrfs_header_bytenr(c), level, btrfs_header_generation(c),
 343                    nr, (u32)BTRFS_NODEPTRS_PER_BLOCK(fs_info) - nr,
 344                    btrfs_header_owner(c));
 345         print_eb_refs_lock(c);
 346         for (i = 0; i < nr; i++) {
 347                 btrfs_node_key_to_cpu(c, &key, i);
 348                 pr_info("\tkey %d (%llu %u %llu) block %llu gen %llu\n",
 349                        i, key.objectid, key.type, key.offset,
 350                        btrfs_node_blockptr(c, i),
 351                        btrfs_node_ptr_generation(c, i));
 352         }
 353         if (!follow)
 354                 return;
 355         for (i = 0; i < nr; i++) {
 356                 struct btrfs_key first_key;
 357                 struct extent_buffer *next;
 358 
 359                 btrfs_node_key_to_cpu(c, &first_key, i);
 360                 next = read_tree_block(fs_info, btrfs_node_blockptr(c, i),
 361                                        btrfs_node_ptr_generation(c, i),
 362                                        level - 1, &first_key);
 363                 if (IS_ERR(next)) {
 364                         continue;
 365                 } else if (!extent_buffer_uptodate(next)) {
 366                         free_extent_buffer(next);
 367                         continue;
 368                 }
 369 
 370                 if (btrfs_is_leaf(next) &&
 371                    level != 1)
 372                         BUG();
 373                 if (btrfs_header_level(next) !=
 374                        level - 1)
 375                         BUG();
 376                 btrfs_print_tree(next, follow);
 377                 free_extent_buffer(next);
 378         }
 379 }

/* [<][>][^][v][top][bottom][index][help] */