Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2007 Oracle.  All rights reserved.
0004  */
0005 
0006 #include "ctree.h"
0007 #include "disk-io.h"
0008 #include "print-tree.h"
0009 
0010 struct root_name_map {
0011     u64 id;
0012     char name[16];
0013 };
0014 
0015 static const struct root_name_map root_map[] = {
0016     { BTRFS_ROOT_TREE_OBJECTID,     "ROOT_TREE"     },
0017     { BTRFS_EXTENT_TREE_OBJECTID,       "EXTENT_TREE"       },
0018     { BTRFS_CHUNK_TREE_OBJECTID,        "CHUNK_TREE"        },
0019     { BTRFS_DEV_TREE_OBJECTID,      "DEV_TREE"      },
0020     { BTRFS_FS_TREE_OBJECTID,       "FS_TREE"       },
0021     { BTRFS_CSUM_TREE_OBJECTID,     "CSUM_TREE"     },
0022     { BTRFS_TREE_LOG_OBJECTID,      "TREE_LOG"      },
0023     { BTRFS_QUOTA_TREE_OBJECTID,        "QUOTA_TREE"        },
0024     { BTRFS_UUID_TREE_OBJECTID,     "UUID_TREE"     },
0025     { BTRFS_FREE_SPACE_TREE_OBJECTID,   "FREE_SPACE_TREE"   },
0026     { BTRFS_BLOCK_GROUP_TREE_OBJECTID,  "BLOCK_GROUP_TREE"  },
0027     { BTRFS_DATA_RELOC_TREE_OBJECTID,   "DATA_RELOC_TREE"   },
0028 };
0029 
0030 const char *btrfs_root_name(const struct btrfs_key *key, char *buf)
0031 {
0032     int i;
0033 
0034     if (key->objectid == BTRFS_TREE_RELOC_OBJECTID) {
0035         snprintf(buf, BTRFS_ROOT_NAME_BUF_LEN,
0036              "TREE_RELOC offset=%llu", key->offset);
0037         return buf;
0038     }
0039 
0040     for (i = 0; i < ARRAY_SIZE(root_map); i++) {
0041         if (root_map[i].id == key->objectid)
0042             return root_map[i].name;
0043     }
0044 
0045     snprintf(buf, BTRFS_ROOT_NAME_BUF_LEN, "%llu", key->objectid);
0046     return buf;
0047 }
0048 
0049 static void print_chunk(struct extent_buffer *eb, struct btrfs_chunk *chunk)
0050 {
0051     int num_stripes = btrfs_chunk_num_stripes(eb, chunk);
0052     int i;
0053     pr_info("\t\tchunk length %llu owner %llu type %llu num_stripes %d\n",
0054            btrfs_chunk_length(eb, chunk), btrfs_chunk_owner(eb, chunk),
0055            btrfs_chunk_type(eb, chunk), num_stripes);
0056     for (i = 0 ; i < num_stripes ; i++) {
0057         pr_info("\t\t\tstripe %d devid %llu offset %llu\n", i,
0058               btrfs_stripe_devid_nr(eb, chunk, i),
0059               btrfs_stripe_offset_nr(eb, chunk, i));
0060     }
0061 }
0062 static void print_dev_item(struct extent_buffer *eb,
0063                struct btrfs_dev_item *dev_item)
0064 {
0065     pr_info("\t\tdev item devid %llu total_bytes %llu bytes used %llu\n",
0066            btrfs_device_id(eb, dev_item),
0067            btrfs_device_total_bytes(eb, dev_item),
0068            btrfs_device_bytes_used(eb, dev_item));
0069 }
0070 static void print_extent_data_ref(struct extent_buffer *eb,
0071                   struct btrfs_extent_data_ref *ref)
0072 {
0073     pr_cont("extent data backref root %llu objectid %llu offset %llu count %u\n",
0074            btrfs_extent_data_ref_root(eb, ref),
0075            btrfs_extent_data_ref_objectid(eb, ref),
0076            btrfs_extent_data_ref_offset(eb, ref),
0077            btrfs_extent_data_ref_count(eb, ref));
0078 }
0079 
0080 static void print_extent_item(struct extent_buffer *eb, int slot, int type)
0081 {
0082     struct btrfs_extent_item *ei;
0083     struct btrfs_extent_inline_ref *iref;
0084     struct btrfs_extent_data_ref *dref;
0085     struct btrfs_shared_data_ref *sref;
0086     struct btrfs_disk_key key;
0087     unsigned long end;
0088     unsigned long ptr;
0089     u32 item_size = btrfs_item_size(eb, slot);
0090     u64 flags;
0091     u64 offset;
0092     int ref_index = 0;
0093 
0094     if (unlikely(item_size < sizeof(*ei))) {
0095         btrfs_print_v0_err(eb->fs_info);
0096         btrfs_handle_fs_error(eb->fs_info, -EINVAL, NULL);
0097     }
0098 
0099     ei = btrfs_item_ptr(eb, slot, struct btrfs_extent_item);
0100     flags = btrfs_extent_flags(eb, ei);
0101 
0102     pr_info("\t\textent refs %llu gen %llu flags %llu\n",
0103            btrfs_extent_refs(eb, ei), btrfs_extent_generation(eb, ei),
0104            flags);
0105 
0106     if ((type == BTRFS_EXTENT_ITEM_KEY) &&
0107         flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
0108         struct btrfs_tree_block_info *info;
0109         info = (struct btrfs_tree_block_info *)(ei + 1);
0110         btrfs_tree_block_key(eb, info, &key);
0111         pr_info("\t\ttree block key (%llu %u %llu) level %d\n",
0112                btrfs_disk_key_objectid(&key), key.type,
0113                btrfs_disk_key_offset(&key),
0114                btrfs_tree_block_level(eb, info));
0115         iref = (struct btrfs_extent_inline_ref *)(info + 1);
0116     } else {
0117         iref = (struct btrfs_extent_inline_ref *)(ei + 1);
0118     }
0119 
0120     ptr = (unsigned long)iref;
0121     end = (unsigned long)ei + item_size;
0122     while (ptr < end) {
0123         iref = (struct btrfs_extent_inline_ref *)ptr;
0124         type = btrfs_extent_inline_ref_type(eb, iref);
0125         offset = btrfs_extent_inline_ref_offset(eb, iref);
0126         pr_info("\t\tref#%d: ", ref_index++);
0127         switch (type) {
0128         case BTRFS_TREE_BLOCK_REF_KEY:
0129             pr_cont("tree block backref root %llu\n", offset);
0130             break;
0131         case BTRFS_SHARED_BLOCK_REF_KEY:
0132             pr_cont("shared block backref parent %llu\n", offset);
0133             /*
0134              * offset is supposed to be a tree block which
0135              * must be aligned to nodesize.
0136              */
0137             if (!IS_ALIGNED(offset, eb->fs_info->sectorsize))
0138                 pr_info(
0139             "\t\t\t(parent %llu not aligned to sectorsize %u)\n",
0140                     offset, eb->fs_info->sectorsize);
0141             break;
0142         case BTRFS_EXTENT_DATA_REF_KEY:
0143             dref = (struct btrfs_extent_data_ref *)(&iref->offset);
0144             print_extent_data_ref(eb, dref);
0145             break;
0146         case BTRFS_SHARED_DATA_REF_KEY:
0147             sref = (struct btrfs_shared_data_ref *)(iref + 1);
0148             pr_cont("shared data backref parent %llu count %u\n",
0149                    offset, btrfs_shared_data_ref_count(eb, sref));
0150             /*
0151              * offset is supposed to be a tree block which
0152              * must be aligned to nodesize.
0153              */
0154             if (!IS_ALIGNED(offset, eb->fs_info->nodesize))
0155                 pr_info(
0156             "\t\t\t(parent %llu not aligned to sectorsize %u)\n",
0157                      offset, eb->fs_info->sectorsize);
0158             break;
0159         default:
0160             pr_cont("(extent %llu has INVALID ref type %d)\n",
0161                   eb->start, type);
0162             return;
0163         }
0164         ptr += btrfs_extent_inline_ref_size(type);
0165     }
0166     WARN_ON(ptr > end);
0167 }
0168 
0169 static void print_uuid_item(struct extent_buffer *l, unsigned long offset,
0170                 u32 item_size)
0171 {
0172     if (!IS_ALIGNED(item_size, sizeof(u64))) {
0173         pr_warn("BTRFS: uuid item with illegal size %lu!\n",
0174             (unsigned long)item_size);
0175         return;
0176     }
0177     while (item_size) {
0178         __le64 subvol_id;
0179 
0180         read_extent_buffer(l, &subvol_id, offset, sizeof(subvol_id));
0181         pr_info("\t\tsubvol_id %llu\n", le64_to_cpu(subvol_id));
0182         item_size -= sizeof(u64);
0183         offset += sizeof(u64);
0184     }
0185 }
0186 
0187 /*
0188  * Helper to output refs and locking status of extent buffer.  Useful to debug
0189  * race condition related problems.
0190  */
0191 static void print_eb_refs_lock(struct extent_buffer *eb)
0192 {
0193 #ifdef CONFIG_BTRFS_DEBUG
0194     btrfs_info(eb->fs_info, "refs %u lock_owner %u current %u",
0195            atomic_read(&eb->refs), eb->lock_owner, current->pid);
0196 #endif
0197 }
0198 
0199 void btrfs_print_leaf(struct extent_buffer *l)
0200 {
0201     struct btrfs_fs_info *fs_info;
0202     int i;
0203     u32 type, nr;
0204     struct btrfs_root_item *ri;
0205     struct btrfs_dir_item *di;
0206     struct btrfs_inode_item *ii;
0207     struct btrfs_block_group_item *bi;
0208     struct btrfs_file_extent_item *fi;
0209     struct btrfs_extent_data_ref *dref;
0210     struct btrfs_shared_data_ref *sref;
0211     struct btrfs_dev_extent *dev_extent;
0212     struct btrfs_key key;
0213     struct btrfs_key found_key;
0214 
0215     if (!l)
0216         return;
0217 
0218     fs_info = l->fs_info;
0219     nr = btrfs_header_nritems(l);
0220 
0221     btrfs_info(fs_info,
0222            "leaf %llu gen %llu total ptrs %d free space %d owner %llu",
0223            btrfs_header_bytenr(l), btrfs_header_generation(l), nr,
0224            btrfs_leaf_free_space(l), btrfs_header_owner(l));
0225     print_eb_refs_lock(l);
0226     for (i = 0 ; i < nr ; i++) {
0227         btrfs_item_key_to_cpu(l, &key, i);
0228         type = key.type;
0229         pr_info("\titem %d key (%llu %u %llu) itemoff %d itemsize %d\n",
0230             i, key.objectid, type, key.offset,
0231             btrfs_item_offset(l, i), btrfs_item_size(l, i));
0232         switch (type) {
0233         case BTRFS_INODE_ITEM_KEY:
0234             ii = btrfs_item_ptr(l, i, struct btrfs_inode_item);
0235             pr_info("\t\tinode generation %llu size %llu mode %o\n",
0236                    btrfs_inode_generation(l, ii),
0237                    btrfs_inode_size(l, ii),
0238                    btrfs_inode_mode(l, ii));
0239             break;
0240         case BTRFS_DIR_ITEM_KEY:
0241             di = btrfs_item_ptr(l, i, struct btrfs_dir_item);
0242             btrfs_dir_item_key_to_cpu(l, di, &found_key);
0243             pr_info("\t\tdir oid %llu type %u\n",
0244                 found_key.objectid,
0245                 btrfs_dir_type(l, di));
0246             break;
0247         case BTRFS_ROOT_ITEM_KEY:
0248             ri = btrfs_item_ptr(l, i, struct btrfs_root_item);
0249             pr_info("\t\troot data bytenr %llu refs %u\n",
0250                 btrfs_disk_root_bytenr(l, ri),
0251                 btrfs_disk_root_refs(l, ri));
0252             break;
0253         case BTRFS_EXTENT_ITEM_KEY:
0254         case BTRFS_METADATA_ITEM_KEY:
0255             print_extent_item(l, i, type);
0256             break;
0257         case BTRFS_TREE_BLOCK_REF_KEY:
0258             pr_info("\t\ttree block backref\n");
0259             break;
0260         case BTRFS_SHARED_BLOCK_REF_KEY:
0261             pr_info("\t\tshared block backref\n");
0262             break;
0263         case BTRFS_EXTENT_DATA_REF_KEY:
0264             dref = btrfs_item_ptr(l, i,
0265                           struct btrfs_extent_data_ref);
0266             print_extent_data_ref(l, dref);
0267             break;
0268         case BTRFS_SHARED_DATA_REF_KEY:
0269             sref = btrfs_item_ptr(l, i,
0270                           struct btrfs_shared_data_ref);
0271             pr_info("\t\tshared data backref count %u\n",
0272                    btrfs_shared_data_ref_count(l, sref));
0273             break;
0274         case BTRFS_EXTENT_DATA_KEY:
0275             fi = btrfs_item_ptr(l, i,
0276                         struct btrfs_file_extent_item);
0277             if (btrfs_file_extent_type(l, fi) ==
0278                 BTRFS_FILE_EXTENT_INLINE) {
0279                 pr_info("\t\tinline extent data size %llu\n",
0280                        btrfs_file_extent_ram_bytes(l, fi));
0281                 break;
0282             }
0283             pr_info("\t\textent data disk bytenr %llu nr %llu\n",
0284                    btrfs_file_extent_disk_bytenr(l, fi),
0285                    btrfs_file_extent_disk_num_bytes(l, fi));
0286             pr_info("\t\textent data offset %llu nr %llu ram %llu\n",
0287                    btrfs_file_extent_offset(l, fi),
0288                    btrfs_file_extent_num_bytes(l, fi),
0289                    btrfs_file_extent_ram_bytes(l, fi));
0290             break;
0291         case BTRFS_EXTENT_REF_V0_KEY:
0292             btrfs_print_v0_err(fs_info);
0293             btrfs_handle_fs_error(fs_info, -EINVAL, NULL);
0294             break;
0295         case BTRFS_BLOCK_GROUP_ITEM_KEY:
0296             bi = btrfs_item_ptr(l, i,
0297                         struct btrfs_block_group_item);
0298             pr_info(
0299            "\t\tblock group used %llu chunk_objectid %llu flags %llu\n",
0300                 btrfs_block_group_used(l, bi),
0301                 btrfs_block_group_chunk_objectid(l, bi),
0302                 btrfs_block_group_flags(l, bi));
0303             break;
0304         case BTRFS_CHUNK_ITEM_KEY:
0305             print_chunk(l, btrfs_item_ptr(l, i,
0306                               struct btrfs_chunk));
0307             break;
0308         case BTRFS_DEV_ITEM_KEY:
0309             print_dev_item(l, btrfs_item_ptr(l, i,
0310                     struct btrfs_dev_item));
0311             break;
0312         case BTRFS_DEV_EXTENT_KEY:
0313             dev_extent = btrfs_item_ptr(l, i,
0314                             struct btrfs_dev_extent);
0315             pr_info("\t\tdev extent chunk_tree %llu\n\t\tchunk objectid %llu chunk offset %llu length %llu\n",
0316                    btrfs_dev_extent_chunk_tree(l, dev_extent),
0317                    btrfs_dev_extent_chunk_objectid(l, dev_extent),
0318                    btrfs_dev_extent_chunk_offset(l, dev_extent),
0319                    btrfs_dev_extent_length(l, dev_extent));
0320             break;
0321         case BTRFS_PERSISTENT_ITEM_KEY:
0322             pr_info("\t\tpersistent item objectid %llu offset %llu\n",
0323                     key.objectid, key.offset);
0324             switch (key.objectid) {
0325             case BTRFS_DEV_STATS_OBJECTID:
0326                 pr_info("\t\tdevice stats\n");
0327                 break;
0328             default:
0329                 pr_info("\t\tunknown persistent item\n");
0330             }
0331             break;
0332         case BTRFS_TEMPORARY_ITEM_KEY:
0333             pr_info("\t\ttemporary item objectid %llu offset %llu\n",
0334                     key.objectid, key.offset);
0335             switch (key.objectid) {
0336             case BTRFS_BALANCE_OBJECTID:
0337                 pr_info("\t\tbalance status\n");
0338                 break;
0339             default:
0340                 pr_info("\t\tunknown temporary item\n");
0341             }
0342             break;
0343         case BTRFS_DEV_REPLACE_KEY:
0344             pr_info("\t\tdev replace\n");
0345             break;
0346         case BTRFS_UUID_KEY_SUBVOL:
0347         case BTRFS_UUID_KEY_RECEIVED_SUBVOL:
0348             print_uuid_item(l, btrfs_item_ptr_offset(l, i),
0349                     btrfs_item_size(l, i));
0350             break;
0351         }
0352     }
0353 }
0354 
0355 void btrfs_print_tree(struct extent_buffer *c, bool follow)
0356 {
0357     struct btrfs_fs_info *fs_info;
0358     int i; u32 nr;
0359     struct btrfs_key key;
0360     int level;
0361 
0362     if (!c)
0363         return;
0364     fs_info = c->fs_info;
0365     nr = btrfs_header_nritems(c);
0366     level = btrfs_header_level(c);
0367     if (level == 0) {
0368         btrfs_print_leaf(c);
0369         return;
0370     }
0371     btrfs_info(fs_info,
0372            "node %llu level %d gen %llu total ptrs %d free spc %u owner %llu",
0373            btrfs_header_bytenr(c), level, btrfs_header_generation(c),
0374            nr, (u32)BTRFS_NODEPTRS_PER_BLOCK(fs_info) - nr,
0375            btrfs_header_owner(c));
0376     print_eb_refs_lock(c);
0377     for (i = 0; i < nr; i++) {
0378         btrfs_node_key_to_cpu(c, &key, i);
0379         pr_info("\tkey %d (%llu %u %llu) block %llu gen %llu\n",
0380                i, key.objectid, key.type, key.offset,
0381                btrfs_node_blockptr(c, i),
0382                btrfs_node_ptr_generation(c, i));
0383     }
0384     if (!follow)
0385         return;
0386     for (i = 0; i < nr; i++) {
0387         struct btrfs_key first_key;
0388         struct extent_buffer *next;
0389 
0390         btrfs_node_key_to_cpu(c, &first_key, i);
0391         next = read_tree_block(fs_info, btrfs_node_blockptr(c, i),
0392                        btrfs_header_owner(c),
0393                        btrfs_node_ptr_generation(c, i),
0394                        level - 1, &first_key);
0395         if (IS_ERR(next))
0396             continue;
0397         if (!extent_buffer_uptodate(next)) {
0398             free_extent_buffer(next);
0399             continue;
0400         }
0401 
0402         if (btrfs_is_leaf(next) &&
0403            level != 1)
0404             BUG();
0405         if (btrfs_header_level(next) !=
0406                level - 1)
0407             BUG();
0408         btrfs_print_tree(next, follow);
0409         free_extent_buffer(next);
0410     }
0411 }