1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2007 Oracle. All rights reserved.
9 #include "print-tree.h"
10 #include "accessors.h"
11 #include "tree-checker.h"
13 #include "raid-stripe-tree.h"
15 struct root_name_map
{
20 static const struct root_name_map root_map
[] = {
21 { BTRFS_ROOT_TREE_OBJECTID
, "ROOT_TREE" },
22 { BTRFS_EXTENT_TREE_OBJECTID
, "EXTENT_TREE" },
23 { BTRFS_CHUNK_TREE_OBJECTID
, "CHUNK_TREE" },
24 { BTRFS_DEV_TREE_OBJECTID
, "DEV_TREE" },
25 { BTRFS_FS_TREE_OBJECTID
, "FS_TREE" },
26 { BTRFS_CSUM_TREE_OBJECTID
, "CSUM_TREE" },
27 { BTRFS_TREE_LOG_OBJECTID
, "TREE_LOG" },
28 { BTRFS_QUOTA_TREE_OBJECTID
, "QUOTA_TREE" },
29 { BTRFS_UUID_TREE_OBJECTID
, "UUID_TREE" },
30 { BTRFS_FREE_SPACE_TREE_OBJECTID
, "FREE_SPACE_TREE" },
31 { BTRFS_BLOCK_GROUP_TREE_OBJECTID
, "BLOCK_GROUP_TREE" },
32 { BTRFS_DATA_RELOC_TREE_OBJECTID
, "DATA_RELOC_TREE" },
33 { BTRFS_RAID_STRIPE_TREE_OBJECTID
, "RAID_STRIPE_TREE" },
36 const char *btrfs_root_name(const struct btrfs_key
*key
, char *buf
)
40 if (key
->objectid
== BTRFS_TREE_RELOC_OBJECTID
) {
41 snprintf(buf
, BTRFS_ROOT_NAME_BUF_LEN
,
42 "TREE_RELOC offset=%llu", key
->offset
);
46 for (i
= 0; i
< ARRAY_SIZE(root_map
); i
++) {
47 if (root_map
[i
].id
== key
->objectid
)
48 return root_map
[i
].name
;
51 snprintf(buf
, BTRFS_ROOT_NAME_BUF_LEN
, "%llu", key
->objectid
);
55 static void print_chunk(const struct extent_buffer
*eb
, struct btrfs_chunk
*chunk
)
57 int num_stripes
= btrfs_chunk_num_stripes(eb
, chunk
);
59 pr_info("\t\tchunk length %llu owner %llu type %llu num_stripes %d\n",
60 btrfs_chunk_length(eb
, chunk
), btrfs_chunk_owner(eb
, chunk
),
61 btrfs_chunk_type(eb
, chunk
), num_stripes
);
62 for (i
= 0 ; i
< num_stripes
; i
++) {
63 pr_info("\t\t\tstripe %d devid %llu offset %llu\n", i
,
64 btrfs_stripe_devid_nr(eb
, chunk
, i
),
65 btrfs_stripe_offset_nr(eb
, chunk
, i
));
68 static void print_dev_item(const struct extent_buffer
*eb
,
69 struct btrfs_dev_item
*dev_item
)
71 pr_info("\t\tdev item devid %llu total_bytes %llu bytes used %llu\n",
72 btrfs_device_id(eb
, dev_item
),
73 btrfs_device_total_bytes(eb
, dev_item
),
74 btrfs_device_bytes_used(eb
, dev_item
));
76 static void print_extent_data_ref(const struct extent_buffer
*eb
,
77 struct btrfs_extent_data_ref
*ref
)
79 pr_cont("extent data backref root %llu objectid %llu offset %llu count %u\n",
80 btrfs_extent_data_ref_root(eb
, ref
),
81 btrfs_extent_data_ref_objectid(eb
, ref
),
82 btrfs_extent_data_ref_offset(eb
, ref
),
83 btrfs_extent_data_ref_count(eb
, ref
));
86 static void print_extent_owner_ref(const struct extent_buffer
*eb
,
87 const struct btrfs_extent_owner_ref
*ref
)
89 ASSERT(btrfs_fs_incompat(eb
->fs_info
, SIMPLE_QUOTA
));
90 pr_cont("extent data owner root %llu\n", btrfs_extent_owner_ref_root_id(eb
, ref
));
93 static void print_extent_item(const struct extent_buffer
*eb
, int slot
, int type
)
95 struct btrfs_extent_item
*ei
;
96 struct btrfs_extent_inline_ref
*iref
;
97 struct btrfs_extent_data_ref
*dref
;
98 struct btrfs_shared_data_ref
*sref
;
99 struct btrfs_extent_owner_ref
*oref
;
100 struct btrfs_disk_key key
;
103 u32 item_size
= btrfs_item_size(eb
, slot
);
108 if (unlikely(item_size
< sizeof(*ei
))) {
109 btrfs_err(eb
->fs_info
,
110 "unexpected extent item size, has %u expect >= %zu",
111 item_size
, sizeof(*ei
));
115 ei
= btrfs_item_ptr(eb
, slot
, struct btrfs_extent_item
);
116 flags
= btrfs_extent_flags(eb
, ei
);
118 pr_info("\t\textent refs %llu gen %llu flags %llu\n",
119 btrfs_extent_refs(eb
, ei
), btrfs_extent_generation(eb
, ei
),
122 if ((type
== BTRFS_EXTENT_ITEM_KEY
) &&
123 flags
& BTRFS_EXTENT_FLAG_TREE_BLOCK
) {
124 struct btrfs_tree_block_info
*info
;
125 info
= (struct btrfs_tree_block_info
*)(ei
+ 1);
126 btrfs_tree_block_key(eb
, info
, &key
);
127 pr_info("\t\ttree block key (%llu %u %llu) level %d\n",
128 btrfs_disk_key_objectid(&key
), key
.type
,
129 btrfs_disk_key_offset(&key
),
130 btrfs_tree_block_level(eb
, info
));
131 iref
= (struct btrfs_extent_inline_ref
*)(info
+ 1);
133 iref
= (struct btrfs_extent_inline_ref
*)(ei
+ 1);
136 ptr
= (unsigned long)iref
;
137 end
= (unsigned long)ei
+ item_size
;
139 iref
= (struct btrfs_extent_inline_ref
*)ptr
;
140 type
= btrfs_extent_inline_ref_type(eb
, iref
);
141 offset
= btrfs_extent_inline_ref_offset(eb
, iref
);
142 pr_info("\t\tref#%d: ", ref_index
++);
144 case BTRFS_TREE_BLOCK_REF_KEY
:
145 pr_cont("tree block backref root %llu\n", offset
);
147 case BTRFS_SHARED_BLOCK_REF_KEY
:
148 pr_cont("shared block backref parent %llu\n", offset
);
150 * offset is supposed to be a tree block which
151 * must be aligned to nodesize.
153 if (!IS_ALIGNED(offset
, eb
->fs_info
->sectorsize
))
155 "\t\t\t(parent %llu not aligned to sectorsize %u)\n",
156 offset
, eb
->fs_info
->sectorsize
);
158 case BTRFS_EXTENT_DATA_REF_KEY
:
159 dref
= (struct btrfs_extent_data_ref
*)(&iref
->offset
);
160 print_extent_data_ref(eb
, dref
);
162 case BTRFS_SHARED_DATA_REF_KEY
:
163 sref
= (struct btrfs_shared_data_ref
*)(iref
+ 1);
164 pr_cont("shared data backref parent %llu count %u\n",
165 offset
, btrfs_shared_data_ref_count(eb
, sref
));
167 * Offset is supposed to be a tree block which must be
168 * aligned to sectorsize.
170 if (!IS_ALIGNED(offset
, eb
->fs_info
->sectorsize
))
172 "\t\t\t(parent %llu not aligned to sectorsize %u)\n",
173 offset
, eb
->fs_info
->sectorsize
);
175 case BTRFS_EXTENT_OWNER_REF_KEY
:
176 oref
= (struct btrfs_extent_owner_ref
*)(&iref
->offset
);
177 print_extent_owner_ref(eb
, oref
);
180 pr_cont("(extent %llu has INVALID ref type %d)\n",
184 ptr
+= btrfs_extent_inline_ref_size(type
);
189 static void print_uuid_item(const struct extent_buffer
*l
, unsigned long offset
,
192 if (!IS_ALIGNED(item_size
, sizeof(u64
))) {
193 pr_warn("BTRFS: uuid item with illegal size %lu!\n",
194 (unsigned long)item_size
);
200 read_extent_buffer(l
, &subvol_id
, offset
, sizeof(subvol_id
));
201 pr_info("\t\tsubvol_id %llu\n", le64_to_cpu(subvol_id
));
202 item_size
-= sizeof(u64
);
203 offset
+= sizeof(u64
);
207 static void print_raid_stripe_key(const struct extent_buffer
*eb
, u32 item_size
,
208 struct btrfs_stripe_extent
*stripe
)
210 const int num_stripes
= btrfs_num_raid_stripes(item_size
);
212 for (int i
= 0; i
< num_stripes
; i
++)
213 pr_info("\t\t\tstride %d devid %llu physical %llu\n",
214 i
, btrfs_raid_stride_devid(eb
, &stripe
->strides
[i
]),
215 btrfs_raid_stride_physical(eb
, &stripe
->strides
[i
]));
219 * Helper to output refs and locking status of extent buffer. Useful to debug
220 * race condition related problems.
222 static void print_eb_refs_lock(const struct extent_buffer
*eb
)
224 #ifdef CONFIG_BTRFS_DEBUG
225 btrfs_info(eb
->fs_info
, "refs %u lock_owner %u current %u",
226 atomic_read(&eb
->refs
), eb
->lock_owner
, current
->pid
);
230 void btrfs_print_leaf(const struct extent_buffer
*l
)
232 struct btrfs_fs_info
*fs_info
;
235 struct btrfs_root_item
*ri
;
236 struct btrfs_dir_item
*di
;
237 struct btrfs_inode_item
*ii
;
238 struct btrfs_block_group_item
*bi
;
239 struct btrfs_file_extent_item
*fi
;
240 struct btrfs_extent_data_ref
*dref
;
241 struct btrfs_shared_data_ref
*sref
;
242 struct btrfs_dev_extent
*dev_extent
;
243 struct btrfs_key key
;
244 struct btrfs_key found_key
;
249 fs_info
= l
->fs_info
;
250 nr
= btrfs_header_nritems(l
);
253 "leaf %llu gen %llu total ptrs %d free space %d owner %llu",
254 btrfs_header_bytenr(l
), btrfs_header_generation(l
), nr
,
255 btrfs_leaf_free_space(l
), btrfs_header_owner(l
));
256 print_eb_refs_lock(l
);
257 for (i
= 0 ; i
< nr
; i
++) {
258 btrfs_item_key_to_cpu(l
, &key
, i
);
260 pr_info("\titem %d key (%llu %u %llu) itemoff %d itemsize %d\n",
261 i
, key
.objectid
, type
, key
.offset
,
262 btrfs_item_offset(l
, i
), btrfs_item_size(l
, i
));
264 case BTRFS_INODE_ITEM_KEY
:
265 ii
= btrfs_item_ptr(l
, i
, struct btrfs_inode_item
);
266 pr_info("\t\tinode generation %llu size %llu mode %o\n",
267 btrfs_inode_generation(l
, ii
),
268 btrfs_inode_size(l
, ii
),
269 btrfs_inode_mode(l
, ii
));
271 case BTRFS_DIR_ITEM_KEY
:
272 di
= btrfs_item_ptr(l
, i
, struct btrfs_dir_item
);
273 btrfs_dir_item_key_to_cpu(l
, di
, &found_key
);
274 pr_info("\t\tdir oid %llu flags %u\n",
276 btrfs_dir_flags(l
, di
));
278 case BTRFS_ROOT_ITEM_KEY
:
279 ri
= btrfs_item_ptr(l
, i
, struct btrfs_root_item
);
280 pr_info("\t\troot data bytenr %llu refs %u\n",
281 btrfs_disk_root_bytenr(l
, ri
),
282 btrfs_disk_root_refs(l
, ri
));
284 case BTRFS_EXTENT_ITEM_KEY
:
285 case BTRFS_METADATA_ITEM_KEY
:
286 print_extent_item(l
, i
, type
);
288 case BTRFS_TREE_BLOCK_REF_KEY
:
289 pr_info("\t\ttree block backref\n");
291 case BTRFS_SHARED_BLOCK_REF_KEY
:
292 pr_info("\t\tshared block backref\n");
294 case BTRFS_EXTENT_DATA_REF_KEY
:
295 dref
= btrfs_item_ptr(l
, i
,
296 struct btrfs_extent_data_ref
);
297 print_extent_data_ref(l
, dref
);
299 case BTRFS_SHARED_DATA_REF_KEY
:
300 sref
= btrfs_item_ptr(l
, i
,
301 struct btrfs_shared_data_ref
);
302 pr_info("\t\tshared data backref count %u\n",
303 btrfs_shared_data_ref_count(l
, sref
));
305 case BTRFS_EXTENT_DATA_KEY
:
306 fi
= btrfs_item_ptr(l
, i
,
307 struct btrfs_file_extent_item
);
308 pr_info("\t\tgeneration %llu type %hhu\n",
309 btrfs_file_extent_generation(l
, fi
),
310 btrfs_file_extent_type(l
, fi
));
311 if (btrfs_file_extent_type(l
, fi
) ==
312 BTRFS_FILE_EXTENT_INLINE
) {
313 pr_info("\t\tinline extent data size %llu\n",
314 btrfs_file_extent_ram_bytes(l
, fi
));
317 pr_info("\t\textent data disk bytenr %llu nr %llu\n",
318 btrfs_file_extent_disk_bytenr(l
, fi
),
319 btrfs_file_extent_disk_num_bytes(l
, fi
));
320 pr_info("\t\textent data offset %llu nr %llu ram %llu\n",
321 btrfs_file_extent_offset(l
, fi
),
322 btrfs_file_extent_num_bytes(l
, fi
),
323 btrfs_file_extent_ram_bytes(l
, fi
));
325 case BTRFS_BLOCK_GROUP_ITEM_KEY
:
326 bi
= btrfs_item_ptr(l
, i
,
327 struct btrfs_block_group_item
);
329 "\t\tblock group used %llu chunk_objectid %llu flags %llu\n",
330 btrfs_block_group_used(l
, bi
),
331 btrfs_block_group_chunk_objectid(l
, bi
),
332 btrfs_block_group_flags(l
, bi
));
334 case BTRFS_CHUNK_ITEM_KEY
:
335 print_chunk(l
, btrfs_item_ptr(l
, i
,
336 struct btrfs_chunk
));
338 case BTRFS_DEV_ITEM_KEY
:
339 print_dev_item(l
, btrfs_item_ptr(l
, i
,
340 struct btrfs_dev_item
));
342 case BTRFS_DEV_EXTENT_KEY
:
343 dev_extent
= btrfs_item_ptr(l
, i
,
344 struct btrfs_dev_extent
);
345 pr_info("\t\tdev extent chunk_tree %llu\n\t\tchunk objectid %llu chunk offset %llu length %llu\n",
346 btrfs_dev_extent_chunk_tree(l
, dev_extent
),
347 btrfs_dev_extent_chunk_objectid(l
, dev_extent
),
348 btrfs_dev_extent_chunk_offset(l
, dev_extent
),
349 btrfs_dev_extent_length(l
, dev_extent
));
351 case BTRFS_PERSISTENT_ITEM_KEY
:
352 pr_info("\t\tpersistent item objectid %llu offset %llu\n",
353 key
.objectid
, key
.offset
);
354 switch (key
.objectid
) {
355 case BTRFS_DEV_STATS_OBJECTID
:
356 pr_info("\t\tdevice stats\n");
359 pr_info("\t\tunknown persistent item\n");
362 case BTRFS_TEMPORARY_ITEM_KEY
:
363 pr_info("\t\ttemporary item objectid %llu offset %llu\n",
364 key
.objectid
, key
.offset
);
365 switch (key
.objectid
) {
366 case BTRFS_BALANCE_OBJECTID
:
367 pr_info("\t\tbalance status\n");
370 pr_info("\t\tunknown temporary item\n");
373 case BTRFS_DEV_REPLACE_KEY
:
374 pr_info("\t\tdev replace\n");
376 case BTRFS_UUID_KEY_SUBVOL
:
377 case BTRFS_UUID_KEY_RECEIVED_SUBVOL
:
378 print_uuid_item(l
, btrfs_item_ptr_offset(l
, i
),
379 btrfs_item_size(l
, i
));
381 case BTRFS_RAID_STRIPE_KEY
:
382 print_raid_stripe_key(l
, btrfs_item_size(l
, i
),
383 btrfs_item_ptr(l
, i
, struct btrfs_stripe_extent
));
389 void btrfs_print_tree(const struct extent_buffer
*c
, bool follow
)
391 struct btrfs_fs_info
*fs_info
;
393 struct btrfs_key key
;
398 fs_info
= c
->fs_info
;
399 nr
= btrfs_header_nritems(c
);
400 level
= btrfs_header_level(c
);
406 "node %llu level %d gen %llu total ptrs %d free spc %u owner %llu",
407 btrfs_header_bytenr(c
), level
, btrfs_header_generation(c
),
408 nr
, (u32
)BTRFS_NODEPTRS_PER_BLOCK(fs_info
) - nr
,
409 btrfs_header_owner(c
));
410 print_eb_refs_lock(c
);
411 for (i
= 0; i
< nr
; i
++) {
412 btrfs_node_key_to_cpu(c
, &key
, i
);
413 pr_info("\tkey %d (%llu %u %llu) block %llu gen %llu\n",
414 i
, key
.objectid
, key
.type
, key
.offset
,
415 btrfs_node_blockptr(c
, i
),
416 btrfs_node_ptr_generation(c
, i
));
420 for (i
= 0; i
< nr
; i
++) {
421 struct btrfs_tree_parent_check check
= {
423 .transid
= btrfs_node_ptr_generation(c
, i
),
424 .owner_root
= btrfs_header_owner(c
),
425 .has_first_key
= true
427 struct extent_buffer
*next
;
429 btrfs_node_key_to_cpu(c
, &check
.first_key
, i
);
430 next
= read_tree_block(fs_info
, btrfs_node_blockptr(c
, i
), &check
);
433 if (!extent_buffer_uptodate(next
)) {
434 free_extent_buffer(next
);
438 if (btrfs_is_leaf(next
) &&
441 if (btrfs_header_level(next
) !=
444 btrfs_print_tree(next
, follow
);
445 free_extent_buffer(next
);