18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2007 Oracle.  All rights reserved.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include "ctree.h"
78c2ecf20Sopenharmony_ci#include "disk-io.h"
88c2ecf20Sopenharmony_ci#include "print-tree.h"
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_cistruct root_name_map {
118c2ecf20Sopenharmony_ci	u64 id;
128c2ecf20Sopenharmony_ci	char name[16];
138c2ecf20Sopenharmony_ci};
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_cistatic const struct root_name_map root_map[] = {
168c2ecf20Sopenharmony_ci	{ BTRFS_ROOT_TREE_OBJECTID,		"ROOT_TREE"		},
178c2ecf20Sopenharmony_ci	{ BTRFS_EXTENT_TREE_OBJECTID,		"EXTENT_TREE"		},
188c2ecf20Sopenharmony_ci	{ BTRFS_CHUNK_TREE_OBJECTID,		"CHUNK_TREE"		},
198c2ecf20Sopenharmony_ci	{ BTRFS_DEV_TREE_OBJECTID,		"DEV_TREE"		},
208c2ecf20Sopenharmony_ci	{ BTRFS_FS_TREE_OBJECTID,		"FS_TREE"		},
218c2ecf20Sopenharmony_ci	{ BTRFS_CSUM_TREE_OBJECTID,		"CSUM_TREE"		},
228c2ecf20Sopenharmony_ci	{ BTRFS_TREE_LOG_OBJECTID,		"TREE_LOG"		},
238c2ecf20Sopenharmony_ci	{ BTRFS_QUOTA_TREE_OBJECTID,		"QUOTA_TREE"		},
248c2ecf20Sopenharmony_ci	{ BTRFS_UUID_TREE_OBJECTID,		"UUID_TREE"		},
258c2ecf20Sopenharmony_ci	{ BTRFS_FREE_SPACE_TREE_OBJECTID,	"FREE_SPACE_TREE"	},
268c2ecf20Sopenharmony_ci	{ BTRFS_DATA_RELOC_TREE_OBJECTID,	"DATA_RELOC_TREE"	},
278c2ecf20Sopenharmony_ci};
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ciconst char *btrfs_root_name(const struct btrfs_key *key, char *buf)
308c2ecf20Sopenharmony_ci{
318c2ecf20Sopenharmony_ci	int i;
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci	if (key->objectid == BTRFS_TREE_RELOC_OBJECTID) {
348c2ecf20Sopenharmony_ci		snprintf(buf, BTRFS_ROOT_NAME_BUF_LEN,
358c2ecf20Sopenharmony_ci			 "TREE_RELOC offset=%llu", key->offset);
368c2ecf20Sopenharmony_ci		return buf;
378c2ecf20Sopenharmony_ci	}
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(root_map); i++) {
408c2ecf20Sopenharmony_ci		if (root_map[i].id == key->objectid)
418c2ecf20Sopenharmony_ci			return root_map[i].name;
428c2ecf20Sopenharmony_ci	}
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	snprintf(buf, BTRFS_ROOT_NAME_BUF_LEN, "%llu", key->objectid);
458c2ecf20Sopenharmony_ci	return buf;
468c2ecf20Sopenharmony_ci}
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_cistatic void print_chunk(struct extent_buffer *eb, struct btrfs_chunk *chunk)
498c2ecf20Sopenharmony_ci{
508c2ecf20Sopenharmony_ci	int num_stripes = btrfs_chunk_num_stripes(eb, chunk);
518c2ecf20Sopenharmony_ci	int i;
528c2ecf20Sopenharmony_ci	pr_info("\t\tchunk length %llu owner %llu type %llu num_stripes %d\n",
538c2ecf20Sopenharmony_ci	       btrfs_chunk_length(eb, chunk), btrfs_chunk_owner(eb, chunk),
548c2ecf20Sopenharmony_ci	       btrfs_chunk_type(eb, chunk), num_stripes);
558c2ecf20Sopenharmony_ci	for (i = 0 ; i < num_stripes ; i++) {
568c2ecf20Sopenharmony_ci		pr_info("\t\t\tstripe %d devid %llu offset %llu\n", i,
578c2ecf20Sopenharmony_ci		      btrfs_stripe_devid_nr(eb, chunk, i),
588c2ecf20Sopenharmony_ci		      btrfs_stripe_offset_nr(eb, chunk, i));
598c2ecf20Sopenharmony_ci	}
608c2ecf20Sopenharmony_ci}
618c2ecf20Sopenharmony_cistatic void print_dev_item(struct extent_buffer *eb,
628c2ecf20Sopenharmony_ci			   struct btrfs_dev_item *dev_item)
638c2ecf20Sopenharmony_ci{
648c2ecf20Sopenharmony_ci	pr_info("\t\tdev item devid %llu total_bytes %llu bytes used %llu\n",
658c2ecf20Sopenharmony_ci	       btrfs_device_id(eb, dev_item),
668c2ecf20Sopenharmony_ci	       btrfs_device_total_bytes(eb, dev_item),
678c2ecf20Sopenharmony_ci	       btrfs_device_bytes_used(eb, dev_item));
688c2ecf20Sopenharmony_ci}
698c2ecf20Sopenharmony_cistatic void print_extent_data_ref(struct extent_buffer *eb,
708c2ecf20Sopenharmony_ci				  struct btrfs_extent_data_ref *ref)
718c2ecf20Sopenharmony_ci{
728c2ecf20Sopenharmony_ci	pr_cont("extent data backref root %llu objectid %llu offset %llu count %u\n",
738c2ecf20Sopenharmony_ci	       btrfs_extent_data_ref_root(eb, ref),
748c2ecf20Sopenharmony_ci	       btrfs_extent_data_ref_objectid(eb, ref),
758c2ecf20Sopenharmony_ci	       btrfs_extent_data_ref_offset(eb, ref),
768c2ecf20Sopenharmony_ci	       btrfs_extent_data_ref_count(eb, ref));
778c2ecf20Sopenharmony_ci}
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_cistatic void print_extent_item(struct extent_buffer *eb, int slot, int type)
808c2ecf20Sopenharmony_ci{
818c2ecf20Sopenharmony_ci	struct btrfs_extent_item *ei;
828c2ecf20Sopenharmony_ci	struct btrfs_extent_inline_ref *iref;
838c2ecf20Sopenharmony_ci	struct btrfs_extent_data_ref *dref;
848c2ecf20Sopenharmony_ci	struct btrfs_shared_data_ref *sref;
858c2ecf20Sopenharmony_ci	struct btrfs_disk_key key;
868c2ecf20Sopenharmony_ci	unsigned long end;
878c2ecf20Sopenharmony_ci	unsigned long ptr;
888c2ecf20Sopenharmony_ci	u32 item_size = btrfs_item_size_nr(eb, slot);
898c2ecf20Sopenharmony_ci	u64 flags;
908c2ecf20Sopenharmony_ci	u64 offset;
918c2ecf20Sopenharmony_ci	int ref_index = 0;
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci	if (unlikely(item_size < sizeof(*ei))) {
948c2ecf20Sopenharmony_ci		btrfs_print_v0_err(eb->fs_info);
958c2ecf20Sopenharmony_ci		btrfs_handle_fs_error(eb->fs_info, -EINVAL, NULL);
968c2ecf20Sopenharmony_ci	}
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci	ei = btrfs_item_ptr(eb, slot, struct btrfs_extent_item);
998c2ecf20Sopenharmony_ci	flags = btrfs_extent_flags(eb, ei);
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci	pr_info("\t\textent refs %llu gen %llu flags %llu\n",
1028c2ecf20Sopenharmony_ci	       btrfs_extent_refs(eb, ei), btrfs_extent_generation(eb, ei),
1038c2ecf20Sopenharmony_ci	       flags);
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	if ((type == BTRFS_EXTENT_ITEM_KEY) &&
1068c2ecf20Sopenharmony_ci	    flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
1078c2ecf20Sopenharmony_ci		struct btrfs_tree_block_info *info;
1088c2ecf20Sopenharmony_ci		info = (struct btrfs_tree_block_info *)(ei + 1);
1098c2ecf20Sopenharmony_ci		btrfs_tree_block_key(eb, info, &key);
1108c2ecf20Sopenharmony_ci		pr_info("\t\ttree block key (%llu %u %llu) level %d\n",
1118c2ecf20Sopenharmony_ci		       btrfs_disk_key_objectid(&key), key.type,
1128c2ecf20Sopenharmony_ci		       btrfs_disk_key_offset(&key),
1138c2ecf20Sopenharmony_ci		       btrfs_tree_block_level(eb, info));
1148c2ecf20Sopenharmony_ci		iref = (struct btrfs_extent_inline_ref *)(info + 1);
1158c2ecf20Sopenharmony_ci	} else {
1168c2ecf20Sopenharmony_ci		iref = (struct btrfs_extent_inline_ref *)(ei + 1);
1178c2ecf20Sopenharmony_ci	}
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	ptr = (unsigned long)iref;
1208c2ecf20Sopenharmony_ci	end = (unsigned long)ei + item_size;
1218c2ecf20Sopenharmony_ci	while (ptr < end) {
1228c2ecf20Sopenharmony_ci		iref = (struct btrfs_extent_inline_ref *)ptr;
1238c2ecf20Sopenharmony_ci		type = btrfs_extent_inline_ref_type(eb, iref);
1248c2ecf20Sopenharmony_ci		offset = btrfs_extent_inline_ref_offset(eb, iref);
1258c2ecf20Sopenharmony_ci		pr_info("\t\tref#%d: ", ref_index++);
1268c2ecf20Sopenharmony_ci		switch (type) {
1278c2ecf20Sopenharmony_ci		case BTRFS_TREE_BLOCK_REF_KEY:
1288c2ecf20Sopenharmony_ci			pr_cont("tree block backref root %llu\n", offset);
1298c2ecf20Sopenharmony_ci			break;
1308c2ecf20Sopenharmony_ci		case BTRFS_SHARED_BLOCK_REF_KEY:
1318c2ecf20Sopenharmony_ci			pr_cont("shared block backref parent %llu\n", offset);
1328c2ecf20Sopenharmony_ci			/*
1338c2ecf20Sopenharmony_ci			 * offset is supposed to be a tree block which
1348c2ecf20Sopenharmony_ci			 * must be aligned to nodesize.
1358c2ecf20Sopenharmony_ci			 */
1368c2ecf20Sopenharmony_ci			if (!IS_ALIGNED(offset, eb->fs_info->sectorsize))
1378c2ecf20Sopenharmony_ci				pr_info(
1388c2ecf20Sopenharmony_ci			"\t\t\t(parent %llu not aligned to sectorsize %u)\n",
1398c2ecf20Sopenharmony_ci					offset, eb->fs_info->sectorsize);
1408c2ecf20Sopenharmony_ci			break;
1418c2ecf20Sopenharmony_ci		case BTRFS_EXTENT_DATA_REF_KEY:
1428c2ecf20Sopenharmony_ci			dref = (struct btrfs_extent_data_ref *)(&iref->offset);
1438c2ecf20Sopenharmony_ci			print_extent_data_ref(eb, dref);
1448c2ecf20Sopenharmony_ci			break;
1458c2ecf20Sopenharmony_ci		case BTRFS_SHARED_DATA_REF_KEY:
1468c2ecf20Sopenharmony_ci			sref = (struct btrfs_shared_data_ref *)(iref + 1);
1478c2ecf20Sopenharmony_ci			pr_cont("shared data backref parent %llu count %u\n",
1488c2ecf20Sopenharmony_ci			       offset, btrfs_shared_data_ref_count(eb, sref));
1498c2ecf20Sopenharmony_ci			/*
1508c2ecf20Sopenharmony_ci			 * Offset is supposed to be a tree block which must be
1518c2ecf20Sopenharmony_ci			 * aligned to sectorsize.
1528c2ecf20Sopenharmony_ci			 */
1538c2ecf20Sopenharmony_ci			if (!IS_ALIGNED(offset, eb->fs_info->sectorsize))
1548c2ecf20Sopenharmony_ci				pr_info(
1558c2ecf20Sopenharmony_ci			"\t\t\t(parent %llu not aligned to sectorsize %u)\n",
1568c2ecf20Sopenharmony_ci				     offset, eb->fs_info->sectorsize);
1578c2ecf20Sopenharmony_ci			break;
1588c2ecf20Sopenharmony_ci		default:
1598c2ecf20Sopenharmony_ci			pr_cont("(extent %llu has INVALID ref type %d)\n",
1608c2ecf20Sopenharmony_ci				  eb->start, type);
1618c2ecf20Sopenharmony_ci			return;
1628c2ecf20Sopenharmony_ci		}
1638c2ecf20Sopenharmony_ci		ptr += btrfs_extent_inline_ref_size(type);
1648c2ecf20Sopenharmony_ci	}
1658c2ecf20Sopenharmony_ci	WARN_ON(ptr > end);
1668c2ecf20Sopenharmony_ci}
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_cistatic void print_uuid_item(struct extent_buffer *l, unsigned long offset,
1698c2ecf20Sopenharmony_ci			    u32 item_size)
1708c2ecf20Sopenharmony_ci{
1718c2ecf20Sopenharmony_ci	if (!IS_ALIGNED(item_size, sizeof(u64))) {
1728c2ecf20Sopenharmony_ci		pr_warn("BTRFS: uuid item with illegal size %lu!\n",
1738c2ecf20Sopenharmony_ci			(unsigned long)item_size);
1748c2ecf20Sopenharmony_ci		return;
1758c2ecf20Sopenharmony_ci	}
1768c2ecf20Sopenharmony_ci	while (item_size) {
1778c2ecf20Sopenharmony_ci		__le64 subvol_id;
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci		read_extent_buffer(l, &subvol_id, offset, sizeof(subvol_id));
1808c2ecf20Sopenharmony_ci		pr_info("\t\tsubvol_id %llu\n",
1818c2ecf20Sopenharmony_ci		       (unsigned long long)le64_to_cpu(subvol_id));
1828c2ecf20Sopenharmony_ci		item_size -= sizeof(u64);
1838c2ecf20Sopenharmony_ci		offset += sizeof(u64);
1848c2ecf20Sopenharmony_ci	}
1858c2ecf20Sopenharmony_ci}
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci/*
1888c2ecf20Sopenharmony_ci * Helper to output refs and locking status of extent buffer.  Useful to debug
1898c2ecf20Sopenharmony_ci * race condition related problems.
1908c2ecf20Sopenharmony_ci */
1918c2ecf20Sopenharmony_cistatic void print_eb_refs_lock(struct extent_buffer *eb)
1928c2ecf20Sopenharmony_ci{
1938c2ecf20Sopenharmony_ci#ifdef CONFIG_BTRFS_DEBUG
1948c2ecf20Sopenharmony_ci	btrfs_info(eb->fs_info,
1958c2ecf20Sopenharmony_ci"refs %u lock (w:%d r:%d bw:%d br:%d sw:%d sr:%d) lock_owner %u current %u",
1968c2ecf20Sopenharmony_ci		   atomic_read(&eb->refs), eb->write_locks,
1978c2ecf20Sopenharmony_ci		   atomic_read(&eb->read_locks),
1988c2ecf20Sopenharmony_ci		   eb->blocking_writers,
1998c2ecf20Sopenharmony_ci		   atomic_read(&eb->blocking_readers),
2008c2ecf20Sopenharmony_ci		   eb->spinning_writers,
2018c2ecf20Sopenharmony_ci		   atomic_read(&eb->spinning_readers),
2028c2ecf20Sopenharmony_ci		   eb->lock_owner, current->pid);
2038c2ecf20Sopenharmony_ci#endif
2048c2ecf20Sopenharmony_ci}
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_civoid btrfs_print_leaf(struct extent_buffer *l)
2078c2ecf20Sopenharmony_ci{
2088c2ecf20Sopenharmony_ci	struct btrfs_fs_info *fs_info;
2098c2ecf20Sopenharmony_ci	int i;
2108c2ecf20Sopenharmony_ci	u32 type, nr;
2118c2ecf20Sopenharmony_ci	struct btrfs_item *item;
2128c2ecf20Sopenharmony_ci	struct btrfs_root_item *ri;
2138c2ecf20Sopenharmony_ci	struct btrfs_dir_item *di;
2148c2ecf20Sopenharmony_ci	struct btrfs_inode_item *ii;
2158c2ecf20Sopenharmony_ci	struct btrfs_block_group_item *bi;
2168c2ecf20Sopenharmony_ci	struct btrfs_file_extent_item *fi;
2178c2ecf20Sopenharmony_ci	struct btrfs_extent_data_ref *dref;
2188c2ecf20Sopenharmony_ci	struct btrfs_shared_data_ref *sref;
2198c2ecf20Sopenharmony_ci	struct btrfs_dev_extent *dev_extent;
2208c2ecf20Sopenharmony_ci	struct btrfs_key key;
2218c2ecf20Sopenharmony_ci	struct btrfs_key found_key;
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_ci	if (!l)
2248c2ecf20Sopenharmony_ci		return;
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ci	fs_info = l->fs_info;
2278c2ecf20Sopenharmony_ci	nr = btrfs_header_nritems(l);
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci	btrfs_info(fs_info,
2308c2ecf20Sopenharmony_ci		   "leaf %llu gen %llu total ptrs %d free space %d owner %llu",
2318c2ecf20Sopenharmony_ci		   btrfs_header_bytenr(l), btrfs_header_generation(l), nr,
2328c2ecf20Sopenharmony_ci		   btrfs_leaf_free_space(l), btrfs_header_owner(l));
2338c2ecf20Sopenharmony_ci	print_eb_refs_lock(l);
2348c2ecf20Sopenharmony_ci	for (i = 0 ; i < nr ; i++) {
2358c2ecf20Sopenharmony_ci		item = btrfs_item_nr(i);
2368c2ecf20Sopenharmony_ci		btrfs_item_key_to_cpu(l, &key, i);
2378c2ecf20Sopenharmony_ci		type = key.type;
2388c2ecf20Sopenharmony_ci		pr_info("\titem %d key (%llu %u %llu) itemoff %d itemsize %d\n",
2398c2ecf20Sopenharmony_ci			i, key.objectid, type, key.offset,
2408c2ecf20Sopenharmony_ci			btrfs_item_offset(l, item), btrfs_item_size(l, item));
2418c2ecf20Sopenharmony_ci		switch (type) {
2428c2ecf20Sopenharmony_ci		case BTRFS_INODE_ITEM_KEY:
2438c2ecf20Sopenharmony_ci			ii = btrfs_item_ptr(l, i, struct btrfs_inode_item);
2448c2ecf20Sopenharmony_ci			pr_info("\t\tinode generation %llu size %llu mode %o\n",
2458c2ecf20Sopenharmony_ci			       btrfs_inode_generation(l, ii),
2468c2ecf20Sopenharmony_ci			       btrfs_inode_size(l, ii),
2478c2ecf20Sopenharmony_ci			       btrfs_inode_mode(l, ii));
2488c2ecf20Sopenharmony_ci			break;
2498c2ecf20Sopenharmony_ci		case BTRFS_DIR_ITEM_KEY:
2508c2ecf20Sopenharmony_ci			di = btrfs_item_ptr(l, i, struct btrfs_dir_item);
2518c2ecf20Sopenharmony_ci			btrfs_dir_item_key_to_cpu(l, di, &found_key);
2528c2ecf20Sopenharmony_ci			pr_info("\t\tdir oid %llu type %u\n",
2538c2ecf20Sopenharmony_ci				found_key.objectid,
2548c2ecf20Sopenharmony_ci				btrfs_dir_type(l, di));
2558c2ecf20Sopenharmony_ci			break;
2568c2ecf20Sopenharmony_ci		case BTRFS_ROOT_ITEM_KEY:
2578c2ecf20Sopenharmony_ci			ri = btrfs_item_ptr(l, i, struct btrfs_root_item);
2588c2ecf20Sopenharmony_ci			pr_info("\t\troot data bytenr %llu refs %u\n",
2598c2ecf20Sopenharmony_ci				btrfs_disk_root_bytenr(l, ri),
2608c2ecf20Sopenharmony_ci				btrfs_disk_root_refs(l, ri));
2618c2ecf20Sopenharmony_ci			break;
2628c2ecf20Sopenharmony_ci		case BTRFS_EXTENT_ITEM_KEY:
2638c2ecf20Sopenharmony_ci		case BTRFS_METADATA_ITEM_KEY:
2648c2ecf20Sopenharmony_ci			print_extent_item(l, i, type);
2658c2ecf20Sopenharmony_ci			break;
2668c2ecf20Sopenharmony_ci		case BTRFS_TREE_BLOCK_REF_KEY:
2678c2ecf20Sopenharmony_ci			pr_info("\t\ttree block backref\n");
2688c2ecf20Sopenharmony_ci			break;
2698c2ecf20Sopenharmony_ci		case BTRFS_SHARED_BLOCK_REF_KEY:
2708c2ecf20Sopenharmony_ci			pr_info("\t\tshared block backref\n");
2718c2ecf20Sopenharmony_ci			break;
2728c2ecf20Sopenharmony_ci		case BTRFS_EXTENT_DATA_REF_KEY:
2738c2ecf20Sopenharmony_ci			dref = btrfs_item_ptr(l, i,
2748c2ecf20Sopenharmony_ci					      struct btrfs_extent_data_ref);
2758c2ecf20Sopenharmony_ci			print_extent_data_ref(l, dref);
2768c2ecf20Sopenharmony_ci			break;
2778c2ecf20Sopenharmony_ci		case BTRFS_SHARED_DATA_REF_KEY:
2788c2ecf20Sopenharmony_ci			sref = btrfs_item_ptr(l, i,
2798c2ecf20Sopenharmony_ci					      struct btrfs_shared_data_ref);
2808c2ecf20Sopenharmony_ci			pr_info("\t\tshared data backref count %u\n",
2818c2ecf20Sopenharmony_ci			       btrfs_shared_data_ref_count(l, sref));
2828c2ecf20Sopenharmony_ci			break;
2838c2ecf20Sopenharmony_ci		case BTRFS_EXTENT_DATA_KEY:
2848c2ecf20Sopenharmony_ci			fi = btrfs_item_ptr(l, i,
2858c2ecf20Sopenharmony_ci					    struct btrfs_file_extent_item);
2868c2ecf20Sopenharmony_ci			if (btrfs_file_extent_type(l, fi) ==
2878c2ecf20Sopenharmony_ci			    BTRFS_FILE_EXTENT_INLINE) {
2888c2ecf20Sopenharmony_ci				pr_info("\t\tinline extent data size %llu\n",
2898c2ecf20Sopenharmony_ci				       btrfs_file_extent_ram_bytes(l, fi));
2908c2ecf20Sopenharmony_ci				break;
2918c2ecf20Sopenharmony_ci			}
2928c2ecf20Sopenharmony_ci			pr_info("\t\textent data disk bytenr %llu nr %llu\n",
2938c2ecf20Sopenharmony_ci			       btrfs_file_extent_disk_bytenr(l, fi),
2948c2ecf20Sopenharmony_ci			       btrfs_file_extent_disk_num_bytes(l, fi));
2958c2ecf20Sopenharmony_ci			pr_info("\t\textent data offset %llu nr %llu ram %llu\n",
2968c2ecf20Sopenharmony_ci			       btrfs_file_extent_offset(l, fi),
2978c2ecf20Sopenharmony_ci			       btrfs_file_extent_num_bytes(l, fi),
2988c2ecf20Sopenharmony_ci			       btrfs_file_extent_ram_bytes(l, fi));
2998c2ecf20Sopenharmony_ci			break;
3008c2ecf20Sopenharmony_ci		case BTRFS_EXTENT_REF_V0_KEY:
3018c2ecf20Sopenharmony_ci			btrfs_print_v0_err(fs_info);
3028c2ecf20Sopenharmony_ci			btrfs_handle_fs_error(fs_info, -EINVAL, NULL);
3038c2ecf20Sopenharmony_ci			break;
3048c2ecf20Sopenharmony_ci		case BTRFS_BLOCK_GROUP_ITEM_KEY:
3058c2ecf20Sopenharmony_ci			bi = btrfs_item_ptr(l, i,
3068c2ecf20Sopenharmony_ci					    struct btrfs_block_group_item);
3078c2ecf20Sopenharmony_ci			pr_info(
3088c2ecf20Sopenharmony_ci		   "\t\tblock group used %llu chunk_objectid %llu flags %llu\n",
3098c2ecf20Sopenharmony_ci				btrfs_block_group_used(l, bi),
3108c2ecf20Sopenharmony_ci				btrfs_block_group_chunk_objectid(l, bi),
3118c2ecf20Sopenharmony_ci				btrfs_block_group_flags(l, bi));
3128c2ecf20Sopenharmony_ci			break;
3138c2ecf20Sopenharmony_ci		case BTRFS_CHUNK_ITEM_KEY:
3148c2ecf20Sopenharmony_ci			print_chunk(l, btrfs_item_ptr(l, i,
3158c2ecf20Sopenharmony_ci						      struct btrfs_chunk));
3168c2ecf20Sopenharmony_ci			break;
3178c2ecf20Sopenharmony_ci		case BTRFS_DEV_ITEM_KEY:
3188c2ecf20Sopenharmony_ci			print_dev_item(l, btrfs_item_ptr(l, i,
3198c2ecf20Sopenharmony_ci					struct btrfs_dev_item));
3208c2ecf20Sopenharmony_ci			break;
3218c2ecf20Sopenharmony_ci		case BTRFS_DEV_EXTENT_KEY:
3228c2ecf20Sopenharmony_ci			dev_extent = btrfs_item_ptr(l, i,
3238c2ecf20Sopenharmony_ci						    struct btrfs_dev_extent);
3248c2ecf20Sopenharmony_ci			pr_info("\t\tdev extent chunk_tree %llu\n\t\tchunk objectid %llu chunk offset %llu length %llu\n",
3258c2ecf20Sopenharmony_ci			       btrfs_dev_extent_chunk_tree(l, dev_extent),
3268c2ecf20Sopenharmony_ci			       btrfs_dev_extent_chunk_objectid(l, dev_extent),
3278c2ecf20Sopenharmony_ci			       btrfs_dev_extent_chunk_offset(l, dev_extent),
3288c2ecf20Sopenharmony_ci			       btrfs_dev_extent_length(l, dev_extent));
3298c2ecf20Sopenharmony_ci			break;
3308c2ecf20Sopenharmony_ci		case BTRFS_PERSISTENT_ITEM_KEY:
3318c2ecf20Sopenharmony_ci			pr_info("\t\tpersistent item objectid %llu offset %llu\n",
3328c2ecf20Sopenharmony_ci					key.objectid, key.offset);
3338c2ecf20Sopenharmony_ci			switch (key.objectid) {
3348c2ecf20Sopenharmony_ci			case BTRFS_DEV_STATS_OBJECTID:
3358c2ecf20Sopenharmony_ci				pr_info("\t\tdevice stats\n");
3368c2ecf20Sopenharmony_ci				break;
3378c2ecf20Sopenharmony_ci			default:
3388c2ecf20Sopenharmony_ci				pr_info("\t\tunknown persistent item\n");
3398c2ecf20Sopenharmony_ci			}
3408c2ecf20Sopenharmony_ci			break;
3418c2ecf20Sopenharmony_ci		case BTRFS_TEMPORARY_ITEM_KEY:
3428c2ecf20Sopenharmony_ci			pr_info("\t\ttemporary item objectid %llu offset %llu\n",
3438c2ecf20Sopenharmony_ci					key.objectid, key.offset);
3448c2ecf20Sopenharmony_ci			switch (key.objectid) {
3458c2ecf20Sopenharmony_ci			case BTRFS_BALANCE_OBJECTID:
3468c2ecf20Sopenharmony_ci				pr_info("\t\tbalance status\n");
3478c2ecf20Sopenharmony_ci				break;
3488c2ecf20Sopenharmony_ci			default:
3498c2ecf20Sopenharmony_ci				pr_info("\t\tunknown temporary item\n");
3508c2ecf20Sopenharmony_ci			}
3518c2ecf20Sopenharmony_ci			break;
3528c2ecf20Sopenharmony_ci		case BTRFS_DEV_REPLACE_KEY:
3538c2ecf20Sopenharmony_ci			pr_info("\t\tdev replace\n");
3548c2ecf20Sopenharmony_ci			break;
3558c2ecf20Sopenharmony_ci		case BTRFS_UUID_KEY_SUBVOL:
3568c2ecf20Sopenharmony_ci		case BTRFS_UUID_KEY_RECEIVED_SUBVOL:
3578c2ecf20Sopenharmony_ci			print_uuid_item(l, btrfs_item_ptr_offset(l, i),
3588c2ecf20Sopenharmony_ci					btrfs_item_size_nr(l, i));
3598c2ecf20Sopenharmony_ci			break;
3608c2ecf20Sopenharmony_ci		}
3618c2ecf20Sopenharmony_ci	}
3628c2ecf20Sopenharmony_ci}
3638c2ecf20Sopenharmony_ci
3648c2ecf20Sopenharmony_civoid btrfs_print_tree(struct extent_buffer *c, bool follow)
3658c2ecf20Sopenharmony_ci{
3668c2ecf20Sopenharmony_ci	struct btrfs_fs_info *fs_info;
3678c2ecf20Sopenharmony_ci	int i; u32 nr;
3688c2ecf20Sopenharmony_ci	struct btrfs_key key;
3698c2ecf20Sopenharmony_ci	int level;
3708c2ecf20Sopenharmony_ci
3718c2ecf20Sopenharmony_ci	if (!c)
3728c2ecf20Sopenharmony_ci		return;
3738c2ecf20Sopenharmony_ci	fs_info = c->fs_info;
3748c2ecf20Sopenharmony_ci	nr = btrfs_header_nritems(c);
3758c2ecf20Sopenharmony_ci	level = btrfs_header_level(c);
3768c2ecf20Sopenharmony_ci	if (level == 0) {
3778c2ecf20Sopenharmony_ci		btrfs_print_leaf(c);
3788c2ecf20Sopenharmony_ci		return;
3798c2ecf20Sopenharmony_ci	}
3808c2ecf20Sopenharmony_ci	btrfs_info(fs_info,
3818c2ecf20Sopenharmony_ci		   "node %llu level %d gen %llu total ptrs %d free spc %u owner %llu",
3828c2ecf20Sopenharmony_ci		   btrfs_header_bytenr(c), level, btrfs_header_generation(c),
3838c2ecf20Sopenharmony_ci		   nr, (u32)BTRFS_NODEPTRS_PER_BLOCK(fs_info) - nr,
3848c2ecf20Sopenharmony_ci		   btrfs_header_owner(c));
3858c2ecf20Sopenharmony_ci	print_eb_refs_lock(c);
3868c2ecf20Sopenharmony_ci	for (i = 0; i < nr; i++) {
3878c2ecf20Sopenharmony_ci		btrfs_node_key_to_cpu(c, &key, i);
3888c2ecf20Sopenharmony_ci		pr_info("\tkey %d (%llu %u %llu) block %llu gen %llu\n",
3898c2ecf20Sopenharmony_ci		       i, key.objectid, key.type, key.offset,
3908c2ecf20Sopenharmony_ci		       btrfs_node_blockptr(c, i),
3918c2ecf20Sopenharmony_ci		       btrfs_node_ptr_generation(c, i));
3928c2ecf20Sopenharmony_ci	}
3938c2ecf20Sopenharmony_ci	if (!follow)
3948c2ecf20Sopenharmony_ci		return;
3958c2ecf20Sopenharmony_ci	for (i = 0; i < nr; i++) {
3968c2ecf20Sopenharmony_ci		struct btrfs_key first_key;
3978c2ecf20Sopenharmony_ci		struct extent_buffer *next;
3988c2ecf20Sopenharmony_ci
3998c2ecf20Sopenharmony_ci		btrfs_node_key_to_cpu(c, &first_key, i);
4008c2ecf20Sopenharmony_ci		next = read_tree_block(fs_info, btrfs_node_blockptr(c, i),
4018c2ecf20Sopenharmony_ci				       btrfs_node_ptr_generation(c, i),
4028c2ecf20Sopenharmony_ci				       level - 1, &first_key);
4038c2ecf20Sopenharmony_ci		if (IS_ERR(next)) {
4048c2ecf20Sopenharmony_ci			continue;
4058c2ecf20Sopenharmony_ci		} else if (!extent_buffer_uptodate(next)) {
4068c2ecf20Sopenharmony_ci			free_extent_buffer(next);
4078c2ecf20Sopenharmony_ci			continue;
4088c2ecf20Sopenharmony_ci		}
4098c2ecf20Sopenharmony_ci
4108c2ecf20Sopenharmony_ci		if (btrfs_is_leaf(next) &&
4118c2ecf20Sopenharmony_ci		   level != 1)
4128c2ecf20Sopenharmony_ci			BUG();
4138c2ecf20Sopenharmony_ci		if (btrfs_header_level(next) !=
4148c2ecf20Sopenharmony_ci		       level - 1)
4158c2ecf20Sopenharmony_ci			BUG();
4168c2ecf20Sopenharmony_ci		btrfs_print_tree(next, follow);
4178c2ecf20Sopenharmony_ci		free_extent_buffer(next);
4188c2ecf20Sopenharmony_ci	}
4198c2ecf20Sopenharmony_ci}
420