All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/11] btrfs: print-tree enhancements
@ 2025-09-15 16:37 fdmanana
  2025-09-15 16:37 ` [PATCH 01/11] btrfs: print-tree: print missing fields for inode items fdmanana
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: fdmanana @ 2025-09-15 16:37 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

The following are several enhancements to the kernel print-tree
implementation. These are motivated by debugging log tree leaves and
apply to the type of items we can find in log trees, and having this
makes the debugging much simpler. Details in the change logs.

Filipe Manana (11):
  btrfs: print-tree: print missing fields for inode items
  btrfs: print-tree: print more information about dir items
  btrfs: print-tree: print dir items for dir index and xattr keys too
  btrfs: print-tree: print information about inode ref items
  btrfs: print-tree: print information about inode extref items
  btrfs: print-tree: print information about dir log items
  btrfs: print-tree: print range information for extent csum items
  btrfs: print-tree: print correct inline extent data size
  btrfs: print-tree: print compression type for file extent items
  btrfs: print-tree: move code for processing file extent item into helper
  btrfs: print-tree: print key types as human readable strings

 fs/btrfs/print-tree.c | 256 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 222 insertions(+), 34 deletions(-)

-- 
2.47.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 01/11] btrfs: print-tree: print missing fields for inode items
  2025-09-15 16:37 [PATCH 00/11] btrfs: print-tree enhancements fdmanana
@ 2025-09-15 16:37 ` fdmanana
  2025-09-15 16:37 ` [PATCH 02/11] btrfs: print-tree: print more information about dir items fdmanana
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: fdmanana @ 2025-09-15 16:37 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

We are not dumping a lot of fields for an inode item which are useful for
debugging whenever we dump a leaf (log replay failure for example), so add
them and make it as close as possible to the print tree implementation in
btrfs-progs (things like converting timespecs to human readable dates and
converting flags to strings are missing since they are not so practical to
do in the kernel).

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/print-tree.c | 37 +++++++++++++++++++++++++++++++------
 1 file changed, 31 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index 74e38da9bd39..ce89974f8fd4 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -227,6 +227,36 @@ static void print_eb_refs_lock(const struct extent_buffer *eb)
 #endif
 }
 
+static void print_timespec(const struct extent_buffer *eb,
+			   struct btrfs_timespec *timespec,
+			   const char *prefix, const char *suffix)
+{
+	const u64 secs = btrfs_timespec_sec(eb, timespec);
+	const u32 nsecs = btrfs_timespec_nsec(eb, timespec);
+
+	pr_info("%s%llu.%u%s", prefix, secs, nsecs, suffix);
+}
+
+static void print_inode_item(const struct extent_buffer *eb, int i)
+{
+	struct btrfs_inode_item *ii = btrfs_item_ptr(eb, i, struct btrfs_inode_item);
+
+	pr_info("\t\tinode generation %llu transid %llu size %llu nbytes %llu\n",
+		btrfs_inode_generation(eb, ii), btrfs_inode_transid(eb, ii),
+		btrfs_inode_size(eb, ii), btrfs_inode_nbytes(eb, ii));
+	pr_info("\t\tblock group %llu mode %o links %u uid %u gid %u\n",
+		btrfs_inode_block_group(eb, ii), btrfs_inode_mode(eb, ii),
+		btrfs_inode_nlink(eb, ii), btrfs_inode_uid(eb, ii),
+		btrfs_inode_gid(eb, ii));
+	pr_info("\t\trdev %llu sequence %llu flags 0x%llx\n",
+		btrfs_inode_rdev(eb, ii), btrfs_inode_sequence(eb, ii),
+		btrfs_inode_flags(eb, ii));
+	print_timespec(eb, &ii->atime, "\t\tatime ", "\n");
+	print_timespec(eb, &ii->ctime, "\t\tctime ", "\n");
+	print_timespec(eb, &ii->mtime, "\t\tmtime ", "\n");
+	print_timespec(eb, &ii->otime, "\t\totime ", "\n");
+}
+
 void btrfs_print_leaf(const struct extent_buffer *l)
 {
 	struct btrfs_fs_info *fs_info;
@@ -234,7 +264,6 @@ void btrfs_print_leaf(const struct extent_buffer *l)
 	u32 type, nr;
 	struct btrfs_root_item *ri;
 	struct btrfs_dir_item *di;
-	struct btrfs_inode_item *ii;
 	struct btrfs_block_group_item *bi;
 	struct btrfs_file_extent_item *fi;
 	struct btrfs_extent_data_ref *dref;
@@ -262,11 +291,7 @@ void btrfs_print_leaf(const struct extent_buffer *l)
 			btrfs_item_offset(l, i), btrfs_item_size(l, i));
 		switch (type) {
 		case BTRFS_INODE_ITEM_KEY:
-			ii = btrfs_item_ptr(l, i, struct btrfs_inode_item);
-			pr_info("\t\tinode generation %llu size %llu mode %o\n",
-			       btrfs_inode_generation(l, ii),
-			       btrfs_inode_size(l, ii),
-			       btrfs_inode_mode(l, ii));
+			print_inode_item(l, i);
 			break;
 		case BTRFS_DIR_ITEM_KEY:
 			di = btrfs_item_ptr(l, i, struct btrfs_dir_item);
-- 
2.47.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 02/11] btrfs: print-tree: print more information about dir items
  2025-09-15 16:37 [PATCH 00/11] btrfs: print-tree enhancements fdmanana
  2025-09-15 16:37 ` [PATCH 01/11] btrfs: print-tree: print missing fields for inode items fdmanana
@ 2025-09-15 16:37 ` fdmanana
  2025-09-15 16:37 ` [PATCH 03/11] btrfs: print-tree: print dir items for dir index and xattr keys too fdmanana
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: fdmanana @ 2025-09-15 16:37 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

Currently we only print the object id component of the location key from a
dir item and the flags. We are missing the whole key, transid and the name
and data lengths. We are also ignoring the fact that we can have multiple
dir item objects encoded in a single item for a BTRFS_DIR_ITEM_KEY key, so
what we print is only for the first item.

Improve on this by iterating on all dir items and print the missing
information. This is done with the same format as in btrfs-progs, what
we miss is printing the names and data since not only that would require
some processing and escaping like in btrfs-progs, but it would also reveal
information that may be sensitive and users may not want to share that in
case that get a leaf dumped in dmesg.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/print-tree.c | 31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)

diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index ce89974f8fd4..df7fe10061ab 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -257,20 +257,41 @@ static void print_inode_item(const struct extent_buffer *eb, int i)
 	print_timespec(eb, &ii->otime, "\t\totime ", "\n");
 }
 
+static void print_dir_item(const struct extent_buffer *eb, int i)
+{
+	const u32 size = btrfs_item_size(eb, i);
+	struct btrfs_dir_item *di = btrfs_item_ptr(eb, i, struct btrfs_dir_item);
+	u32 cur = 0;
+
+	while (cur < size) {
+		const u32 name_len = btrfs_dir_name_len(eb, di);
+		const u32 data_len = btrfs_dir_data_len(eb, di);
+		const u32 len = sizeof(*di) + name_len + data_len;
+		struct btrfs_key location;
+
+		btrfs_dir_item_key_to_cpu(eb, di, &location);
+		pr_info("\t\tlocation key (%llu %u %llu) type %d\n",
+			location.objectid, location.type, location.offset,
+			btrfs_dir_ftype(eb, di));
+		pr_info("\t\ttransid %llu data_len %u name_len %u\n",
+			btrfs_dir_transid(eb, di), data_len, name_len);
+		di = (struct btrfs_dir_item *)((char *)di + len);
+		cur += len;
+	}
+}
+
 void btrfs_print_leaf(const struct extent_buffer *l)
 {
 	struct btrfs_fs_info *fs_info;
 	int i;
 	u32 type, nr;
 	struct btrfs_root_item *ri;
-	struct btrfs_dir_item *di;
 	struct btrfs_block_group_item *bi;
 	struct btrfs_file_extent_item *fi;
 	struct btrfs_extent_data_ref *dref;
 	struct btrfs_shared_data_ref *sref;
 	struct btrfs_dev_extent *dev_extent;
 	struct btrfs_key key;
-	struct btrfs_key found_key;
 
 	if (!l)
 		return;
@@ -294,11 +315,7 @@ void btrfs_print_leaf(const struct extent_buffer *l)
 			print_inode_item(l, i);
 			break;
 		case BTRFS_DIR_ITEM_KEY:
-			di = btrfs_item_ptr(l, i, struct btrfs_dir_item);
-			btrfs_dir_item_key_to_cpu(l, di, &found_key);
-			pr_info("\t\tdir oid %llu flags %u\n",
-				found_key.objectid,
-				btrfs_dir_flags(l, di));
+			print_dir_item(l, i);
 			break;
 		case BTRFS_ROOT_ITEM_KEY:
 			ri = btrfs_item_ptr(l, i, struct btrfs_root_item);
-- 
2.47.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 03/11] btrfs: print-tree: print dir items for dir index and xattr keys too
  2025-09-15 16:37 [PATCH 00/11] btrfs: print-tree enhancements fdmanana
  2025-09-15 16:37 ` [PATCH 01/11] btrfs: print-tree: print missing fields for inode items fdmanana
  2025-09-15 16:37 ` [PATCH 02/11] btrfs: print-tree: print more information about dir items fdmanana
@ 2025-09-15 16:37 ` fdmanana
  2025-09-15 16:37 ` [PATCH 04/11] btrfs: print-tree: print information about inode ref items fdmanana
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: fdmanana @ 2025-09-15 16:37 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

Currently we only print the dir items for BTRFS_DIR_ITEM_KEY keys, but
we also have dir items for BTRFS_DIR_INDEX_KEY and BTRFS_XATTR_ITEM_KEY
keys too. So print them for those keys too.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/print-tree.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index df7fe10061ab..5ae611cb3f2e 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -315,6 +315,8 @@ void btrfs_print_leaf(const struct extent_buffer *l)
 			print_inode_item(l, i);
 			break;
 		case BTRFS_DIR_ITEM_KEY:
+		case BTRFS_DIR_INDEX_KEY:
+		case BTRFS_XATTR_ITEM_KEY:
 			print_dir_item(l, i);
 			break;
 		case BTRFS_ROOT_ITEM_KEY:
-- 
2.47.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 04/11] btrfs: print-tree: print information about inode ref items
  2025-09-15 16:37 [PATCH 00/11] btrfs: print-tree enhancements fdmanana
                   ` (2 preceding siblings ...)
  2025-09-15 16:37 ` [PATCH 03/11] btrfs: print-tree: print dir items for dir index and xattr keys too fdmanana
@ 2025-09-15 16:37 ` fdmanana
  2025-09-15 16:37 ` [PATCH 05/11] btrfs: print-tree: print information about inode extref items fdmanana
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: fdmanana @ 2025-09-15 16:37 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

Currently we ignore inode ref items, we just print their key, item offset
in the leaf and their size, no information about their content like the
index number, name length and name.

Improve on this by printing the index and name length in the same format
as btrfs-progs. Note that we don't print the name, as that would require
some processing and escaping like we do in btrfs-progs, and that could
expose sensitive information for some users in case they share their
dmesg/syslog and it contains a leaf dump. So for now leave names out.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/print-tree.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index 5ae611cb3f2e..7a7156257d59 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -280,6 +280,23 @@ static void print_dir_item(const struct extent_buffer *eb, int i)
 	}
 }
 
+static void print_inode_ref_item(const struct extent_buffer *eb, int i)
+{
+	const u32 size = btrfs_item_size(eb, i);
+	struct btrfs_inode_ref *ref = btrfs_item_ptr(eb, i, struct btrfs_inode_ref);
+	u32 cur = 0;
+
+	while (cur < size) {
+		const u64 index = btrfs_inode_ref_index(eb, ref);
+		const u32 name_len = btrfs_inode_ref_name_len(eb, ref);
+		const u32 len = sizeof(*ref) + name_len;
+
+		pr_info("\t\tindex %llu name_len %u\n", index, name_len);
+		ref = (struct btrfs_inode_ref *)((char *)ref + len);
+		cur += len;
+	}
+}
+
 void btrfs_print_leaf(const struct extent_buffer *l)
 {
 	struct btrfs_fs_info *fs_info;
@@ -314,6 +331,9 @@ void btrfs_print_leaf(const struct extent_buffer *l)
 		case BTRFS_INODE_ITEM_KEY:
 			print_inode_item(l, i);
 			break;
+		case BTRFS_INODE_REF_KEY:
+			print_inode_ref_item(l, i);
+			break;
 		case BTRFS_DIR_ITEM_KEY:
 		case BTRFS_DIR_INDEX_KEY:
 		case BTRFS_XATTR_ITEM_KEY:
-- 
2.47.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 05/11] btrfs: print-tree: print information about inode extref items
  2025-09-15 16:37 [PATCH 00/11] btrfs: print-tree enhancements fdmanana
                   ` (3 preceding siblings ...)
  2025-09-15 16:37 ` [PATCH 04/11] btrfs: print-tree: print information about inode ref items fdmanana
@ 2025-09-15 16:37 ` fdmanana
  2025-09-15 16:37 ` [PATCH 06/11] btrfs: print-tree: print information about dir log items fdmanana
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: fdmanana @ 2025-09-15 16:37 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

Currently we ignore inode extref items, we just print their key, item
offset in the leaf and their size, no information about their content
like the index number, parent inode, name length and name.

Improve on this by printing the index, parent and name length in the same
format as btrfs-progs. Note that we don't print the name, as that would
require some processing and escaping like we do in btrfs-progs, and that
could expose sensitive information for some users in case they share their
dmesg/syslog and it contains a leaf dump. So for now leave names out.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/print-tree.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index 7a7156257d59..0a2a6e82a3bf 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -297,6 +297,26 @@ static void print_inode_ref_item(const struct extent_buffer *eb, int i)
 	}
 }
 
+static void print_inode_extref_item(const struct extent_buffer *eb, int i)
+{
+	const u32 size = btrfs_item_size(eb, i);
+	struct btrfs_inode_extref *extref;
+	u32 cur = 0;
+
+	extref = btrfs_item_ptr(eb, i, struct btrfs_inode_extref);
+	while (cur < size) {
+		const u64 index = btrfs_inode_extref_index(eb, extref);
+		const u32 name_len = btrfs_inode_extref_name_len(eb, extref);
+		const u64 parent = btrfs_inode_extref_parent(eb, extref);
+		const u32 len = sizeof(*extref) + name_len;
+
+		pr_info("\t\tindex %llu parent %llu name_len %u\n",
+			index, parent, name_len);
+		extref = (struct btrfs_inode_extref *)((char *)extref + len);
+		cur += len;
+	}
+}
+
 void btrfs_print_leaf(const struct extent_buffer *l)
 {
 	struct btrfs_fs_info *fs_info;
@@ -334,6 +354,9 @@ void btrfs_print_leaf(const struct extent_buffer *l)
 		case BTRFS_INODE_REF_KEY:
 			print_inode_ref_item(l, i);
 			break;
+		case BTRFS_INODE_EXTREF_KEY:
+			print_inode_extref_item(l, i);
+			break;
 		case BTRFS_DIR_ITEM_KEY:
 		case BTRFS_DIR_INDEX_KEY:
 		case BTRFS_XATTR_ITEM_KEY:
-- 
2.47.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 06/11] btrfs: print-tree: print information about dir log items
  2025-09-15 16:37 [PATCH 00/11] btrfs: print-tree enhancements fdmanana
                   ` (4 preceding siblings ...)
  2025-09-15 16:37 ` [PATCH 05/11] btrfs: print-tree: print information about inode extref items fdmanana
@ 2025-09-15 16:37 ` fdmanana
  2025-09-15 16:37 ` [PATCH 07/11] btrfs: print-tree: print range information for extent csum items fdmanana
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: fdmanana @ 2025-09-15 16:37 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

We currently don't print information about dir log items (other than the
key, item offset and item size), which is useful to look at when debugging
problems with a log tree. So print their specific information (currently
they only have an end index number) in a format similar to btrfs-progs.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/print-tree.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index 0a2a6e82a3bf..a66aced1d29c 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -317,6 +317,14 @@ static void print_inode_extref_item(const struct extent_buffer *eb, int i)
 	}
 }
 
+static void print_dir_log_index_item(const struct extent_buffer *eb, int i)
+{
+	struct btrfs_dir_log_item *dlog;
+
+	dlog = btrfs_item_ptr(eb, i, struct btrfs_dir_log_item);
+	pr_info("\t\tdir log end %llu\n", btrfs_dir_log_end(eb, dlog));
+}
+
 void btrfs_print_leaf(const struct extent_buffer *l)
 {
 	struct btrfs_fs_info *fs_info;
@@ -362,6 +370,9 @@ void btrfs_print_leaf(const struct extent_buffer *l)
 		case BTRFS_XATTR_ITEM_KEY:
 			print_dir_item(l, i);
 			break;
+		case BTRFS_DIR_LOG_INDEX_KEY:
+			print_dir_log_index_item(l, i);
+			break;
 		case BTRFS_ROOT_ITEM_KEY:
 			ri = btrfs_item_ptr(l, i, struct btrfs_root_item);
 			pr_info("\t\troot data bytenr %llu refs %u\n",
-- 
2.47.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 07/11] btrfs: print-tree: print range information for extent csum items
  2025-09-15 16:37 [PATCH 00/11] btrfs: print-tree enhancements fdmanana
                   ` (5 preceding siblings ...)
  2025-09-15 16:37 ` [PATCH 06/11] btrfs: print-tree: print information about dir log items fdmanana
@ 2025-09-15 16:37 ` fdmanana
  2025-09-15 16:37 ` [PATCH 08/11] btrfs: print-tree: print correct inline extent data size fdmanana
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: fdmanana @ 2025-09-15 16:37 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

Currently we don't print anything for extent csum items other than the
generic line with the key, item offset and item size. While one can still
determine the range the extent csum covers by doing a few simple
computations, it makes it more time consuming to analyse a leaf dump.
So add a line that prints information about the range covered by the
checksum using the same format as btrfs-progs. This is useful when
debugging log tree issues since we log extent csum items for new extents.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/print-tree.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index a66aced1d29c..c2898fa6d4ba 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -325,6 +325,18 @@ static void print_dir_log_index_item(const struct extent_buffer *eb, int i)
 	pr_info("\t\tdir log end %llu\n", btrfs_dir_log_end(eb, dlog));
 }
 
+static void print_extent_csum(const struct extent_buffer *eb, int i)
+{
+	const struct btrfs_fs_info *fs_info = eb->fs_info;
+	const u32 size = btrfs_item_size(eb, i);
+	const u32 csum_bytes = (size / fs_info->csum_size) * fs_info->sectorsize;
+	struct btrfs_key key;
+
+	btrfs_item_key_to_cpu(eb, &key, i);
+	pr_info("\t\trange start %llu end %llu length %u\n",
+		key.offset, key.offset + csum_bytes, csum_bytes);
+}
+
 void btrfs_print_leaf(const struct extent_buffer *l)
 {
 	struct btrfs_fs_info *fs_info;
@@ -373,6 +385,9 @@ void btrfs_print_leaf(const struct extent_buffer *l)
 		case BTRFS_DIR_LOG_INDEX_KEY:
 			print_dir_log_index_item(l, i);
 			break;
+		case BTRFS_EXTENT_CSUM_KEY:
+			print_extent_csum(l, i);
+			break;
 		case BTRFS_ROOT_ITEM_KEY:
 			ri = btrfs_item_ptr(l, i, struct btrfs_root_item);
 			pr_info("\t\troot data bytenr %llu refs %u\n",
-- 
2.47.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 08/11] btrfs: print-tree: print correct inline extent data size
  2025-09-15 16:37 [PATCH 00/11] btrfs: print-tree enhancements fdmanana
                   ` (6 preceding siblings ...)
  2025-09-15 16:37 ` [PATCH 07/11] btrfs: print-tree: print range information for extent csum items fdmanana
@ 2025-09-15 16:37 ` fdmanana
  2025-09-15 16:37 ` [PATCH 09/11] btrfs: print-tree: print compression type for file extent items fdmanana
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: fdmanana @ 2025-09-15 16:37 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

We are advertising the ram_bytes of an inline extent as its data size, but
that is not true for compressed extents. The ram_bytes corresponds to the
uncompressed data size while the data size (compressed data) is given by
btrfs_file_extent_inline_item_len(). So fix this and print both values in
the same format as in btrfs-progs.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/print-tree.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index c2898fa6d4ba..835b41874a7a 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -6,6 +6,7 @@
 #include "messages.h"
 #include "ctree.h"
 #include "disk-io.h"
+#include "file-item.h"
 #include "print-tree.h"
 #include "accessors.h"
 #include "tree-checker.h"
@@ -423,8 +424,9 @@ void btrfs_print_leaf(const struct extent_buffer *l)
 				btrfs_file_extent_type(l, fi));
 			if (btrfs_file_extent_type(l, fi) ==
 			    BTRFS_FILE_EXTENT_INLINE) {
-				pr_info("\t\tinline extent data size %llu\n",
-				       btrfs_file_extent_ram_bytes(l, fi));
+				pr_info("\t\tinline extent data size %u ram_bytes %llu\n",
+					btrfs_file_extent_inline_item_len(l, i),
+					btrfs_file_extent_ram_bytes(l, fi));
 				break;
 			}
 			pr_info("\t\textent data disk bytenr %llu nr %llu\n",
-- 
2.47.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 09/11] btrfs: print-tree: print compression type for file extent items
  2025-09-15 16:37 [PATCH 00/11] btrfs: print-tree enhancements fdmanana
                   ` (7 preceding siblings ...)
  2025-09-15 16:37 ` [PATCH 08/11] btrfs: print-tree: print correct inline extent data size fdmanana
@ 2025-09-15 16:37 ` fdmanana
  2025-09-15 16:37 ` [PATCH 10/11] btrfs: print-tree: move code for processing file extent item into helper fdmanana
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: fdmanana @ 2025-09-15 16:37 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

We are not printing anything about the compression type, so add that
useful information in the same format as btrfs-progs.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/print-tree.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index 835b41874a7a..417e3860cd25 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -424,9 +424,10 @@ void btrfs_print_leaf(const struct extent_buffer *l)
 				btrfs_file_extent_type(l, fi));
 			if (btrfs_file_extent_type(l, fi) ==
 			    BTRFS_FILE_EXTENT_INLINE) {
-				pr_info("\t\tinline extent data size %u ram_bytes %llu\n",
+				pr_info("\t\tinline extent data size %u ram_bytes %llu compression %hhu\n",
 					btrfs_file_extent_inline_item_len(l, i),
-					btrfs_file_extent_ram_bytes(l, fi));
+					btrfs_file_extent_ram_bytes(l, fi),
+					btrfs_file_extent_compression(l, fi));
 				break;
 			}
 			pr_info("\t\textent data disk bytenr %llu nr %llu\n",
@@ -436,6 +437,8 @@ void btrfs_print_leaf(const struct extent_buffer *l)
 			       btrfs_file_extent_offset(l, fi),
 			       btrfs_file_extent_num_bytes(l, fi),
 			       btrfs_file_extent_ram_bytes(l, fi));
+			pr_info("\t\textent compression %hhu\n",
+				btrfs_file_extent_compression(l, fi));
 			break;
 		case BTRFS_BLOCK_GROUP_ITEM_KEY:
 			bi = btrfs_item_ptr(l, i,
-- 
2.47.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 10/11] btrfs: print-tree: move code for processing file extent item into helper
  2025-09-15 16:37 [PATCH 00/11] btrfs: print-tree enhancements fdmanana
                   ` (8 preceding siblings ...)
  2025-09-15 16:37 ` [PATCH 09/11] btrfs: print-tree: print compression type for file extent items fdmanana
@ 2025-09-15 16:37 ` fdmanana
  2025-09-15 16:37 ` [PATCH 11/11] btrfs: print-tree: print key types as human readable strings fdmanana
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: fdmanana @ 2025-09-15 16:37 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

The code for processing file extent items is quite large and it's better
to have it in a dedicated helper rather than in a huge switch statement,
just like we do in btrfs-progs.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/print-tree.c | 52 ++++++++++++++++++++++++-------------------
 1 file changed, 29 insertions(+), 23 deletions(-)

diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index 417e3860cd25..02ad18abefb9 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -338,6 +338,34 @@ static void print_extent_csum(const struct extent_buffer *eb, int i)
 		key.offset, key.offset + csum_bytes, csum_bytes);
 }
 
+static void print_file_extent_item(const struct extent_buffer *eb, int i)
+{
+	struct btrfs_file_extent_item *fi;
+
+	fi = btrfs_item_ptr(eb, i, struct btrfs_file_extent_item);
+	pr_info("\t\tgeneration %llu type %hhu\n",
+		btrfs_file_extent_generation(eb, fi),
+		btrfs_file_extent_type(eb, fi));
+
+	if (btrfs_file_extent_type(eb, fi) == BTRFS_FILE_EXTENT_INLINE) {
+		pr_info("\t\tinline extent data size %u ram_bytes %llu compression %hhu\n",
+			btrfs_file_extent_inline_item_len(eb, i),
+			btrfs_file_extent_ram_bytes(eb, fi),
+			btrfs_file_extent_compression(eb, fi));
+		return;
+	}
+
+	pr_info("\t\textent data disk bytenr %llu nr %llu\n",
+		btrfs_file_extent_disk_bytenr(eb, fi),
+		btrfs_file_extent_disk_num_bytes(eb, fi));
+	pr_info("\t\textent data offset %llu nr %llu ram %llu\n",
+		btrfs_file_extent_offset(eb, fi),
+		btrfs_file_extent_num_bytes(eb, fi),
+		btrfs_file_extent_ram_bytes(eb, fi));
+	pr_info("\t\textent compression %hhu\n",
+		btrfs_file_extent_compression(eb, fi));
+}
+
 void btrfs_print_leaf(const struct extent_buffer *l)
 {
 	struct btrfs_fs_info *fs_info;
@@ -345,7 +373,6 @@ void btrfs_print_leaf(const struct extent_buffer *l)
 	u32 type, nr;
 	struct btrfs_root_item *ri;
 	struct btrfs_block_group_item *bi;
-	struct btrfs_file_extent_item *fi;
 	struct btrfs_extent_data_ref *dref;
 	struct btrfs_shared_data_ref *sref;
 	struct btrfs_dev_extent *dev_extent;
@@ -417,28 +444,7 @@ void btrfs_print_leaf(const struct extent_buffer *l)
 			       btrfs_shared_data_ref_count(l, sref));
 			break;
 		case BTRFS_EXTENT_DATA_KEY:
-			fi = btrfs_item_ptr(l, i,
-					    struct btrfs_file_extent_item);
-			pr_info("\t\tgeneration %llu type %hhu\n",
-				btrfs_file_extent_generation(l, fi),
-				btrfs_file_extent_type(l, fi));
-			if (btrfs_file_extent_type(l, fi) ==
-			    BTRFS_FILE_EXTENT_INLINE) {
-				pr_info("\t\tinline extent data size %u ram_bytes %llu compression %hhu\n",
-					btrfs_file_extent_inline_item_len(l, i),
-					btrfs_file_extent_ram_bytes(l, fi),
-					btrfs_file_extent_compression(l, fi));
-				break;
-			}
-			pr_info("\t\textent data disk bytenr %llu nr %llu\n",
-			       btrfs_file_extent_disk_bytenr(l, fi),
-			       btrfs_file_extent_disk_num_bytes(l, fi));
-			pr_info("\t\textent data offset %llu nr %llu ram %llu\n",
-			       btrfs_file_extent_offset(l, fi),
-			       btrfs_file_extent_num_bytes(l, fi),
-			       btrfs_file_extent_ram_bytes(l, fi));
-			pr_info("\t\textent compression %hhu\n",
-				btrfs_file_extent_compression(l, fi));
+			print_file_extent_item(l, i);
 			break;
 		case BTRFS_BLOCK_GROUP_ITEM_KEY:
 			bi = btrfs_item_ptr(l, i,
-- 
2.47.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 11/11] btrfs: print-tree: print key types as human readable strings
  2025-09-15 16:37 [PATCH 00/11] btrfs: print-tree enhancements fdmanana
                   ` (9 preceding siblings ...)
  2025-09-15 16:37 ` [PATCH 10/11] btrfs: print-tree: move code for processing file extent item into helper fdmanana
@ 2025-09-15 16:37 ` fdmanana
  2025-09-15 22:02 ` [PATCH 00/11] btrfs: print-tree enhancements Qu Wenruo
  2025-09-16  6:46 ` Johannes Thumshirn
  12 siblings, 0 replies; 14+ messages in thread
From: fdmanana @ 2025-09-15 16:37 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

Looking at a leaf dump from the kernel's print-tree implementation is not
so friendly to analyse since key types are printed as numbers. Improve on
this by printing key types as strings that are a diminutive of the macro
names for key types, just like we do in btrfs-progs.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/print-tree.c | 68 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 66 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index 02ad18abefb9..62b993fae54f 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -13,6 +13,12 @@
 #include "volumes.h"
 #include "raid-stripe-tree.h"
 
+/*
+ * Large enough buffer size for the stringification of any key type yet short
+ * enough to use the stack and avoid allocations.
+ */
+#define KEY_TYPE_BUF_SIZE 32
+
 struct root_name_map {
 	u64 id;
 	const char *name;
@@ -366,6 +372,60 @@ static void print_file_extent_item(const struct extent_buffer *eb, int i)
 		btrfs_file_extent_compression(eb, fi));
 }
 
+static void key_type_string(const struct btrfs_key *key, char *buf, int buf_size)
+{
+	static const char *key_to_str[256] = {
+		[BTRFS_INODE_ITEM_KEY]			= "INODE_ITEM",
+		[BTRFS_INODE_REF_KEY]			= "INODE_REF",
+		[BTRFS_INODE_EXTREF_KEY]		= "INODE_EXTREF",
+		[BTRFS_DIR_ITEM_KEY]			= "DIR_ITEM",
+		[BTRFS_DIR_INDEX_KEY]			= "DIR_INDEX",
+		[BTRFS_DIR_LOG_ITEM_KEY]		= "DIR_LOG_ITEM",
+		[BTRFS_DIR_LOG_INDEX_KEY]		= "DIR_LOG_INDEX",
+		[BTRFS_XATTR_ITEM_KEY]			= "XATTR_ITEM",
+		[BTRFS_VERITY_DESC_ITEM_KEY]		= "VERITY_DESC_ITEM",
+		[BTRFS_VERITY_MERKLE_ITEM_KEY]		= "VERITY_MERKLE_ITEM",
+		[BTRFS_ORPHAN_ITEM_KEY]			= "ORPHAN_ITEM",
+		[BTRFS_ROOT_ITEM_KEY]			= "ROOT_ITEM",
+		[BTRFS_ROOT_REF_KEY]			= "ROOT_REF",
+		[BTRFS_ROOT_BACKREF_KEY]		= "ROOT_BACKREF",
+		[BTRFS_EXTENT_ITEM_KEY]			= "EXTENT_ITEM",
+		[BTRFS_METADATA_ITEM_KEY]		= "METADATA_ITEM",
+		[BTRFS_TREE_BLOCK_REF_KEY]		= "TREE_BLOCK_REF",
+		[BTRFS_SHARED_BLOCK_REF_KEY]		= "SHARED_BLOCK_REF",
+		[BTRFS_EXTENT_DATA_REF_KEY]		= "EXTENT_DATA_REF",
+		[BTRFS_SHARED_DATA_REF_KEY]		= "SHARED_DATA_REF",
+		[BTRFS_EXTENT_OWNER_REF_KEY]		= "EXTENT_OWNER_REF",
+		[BTRFS_EXTENT_CSUM_KEY]			= "EXTENT_CSUM",
+		[BTRFS_EXTENT_DATA_KEY]			= "EXTENT_DATA",
+		[BTRFS_BLOCK_GROUP_ITEM_KEY]		= "BLOCK_GROUP_ITEM",
+		[BTRFS_FREE_SPACE_INFO_KEY]		= "FREE_SPACE_INFO",
+		[BTRFS_FREE_SPACE_EXTENT_KEY]		= "FREE_SPACE_EXTENT",
+		[BTRFS_FREE_SPACE_BITMAP_KEY]		= "FREE_SPACE_BITMAP",
+		[BTRFS_CHUNK_ITEM_KEY]			= "CHUNK_ITEM",
+		[BTRFS_DEV_ITEM_KEY]			= "DEV_ITEM",
+		[BTRFS_DEV_EXTENT_KEY]			= "DEV_EXTENT",
+		[BTRFS_TEMPORARY_ITEM_KEY]		= "TEMPORARY_ITEM",
+		[BTRFS_DEV_REPLACE_KEY]			= "DEV_REPLACE",
+		[BTRFS_STRING_ITEM_KEY]			= "STRING_ITEM",
+		[BTRFS_QGROUP_STATUS_KEY]		= "QGROUP_STATUS",
+		[BTRFS_QGROUP_RELATION_KEY]		= "QGROUP_RELATION",
+		[BTRFS_QGROUP_INFO_KEY]			= "QGROUP_INFO",
+		[BTRFS_QGROUP_LIMIT_KEY]		= "QGROUP_LIMIT",
+		[BTRFS_PERSISTENT_ITEM_KEY]		= "PERSISTENT_ITEM",
+		[BTRFS_UUID_KEY_SUBVOL]			= "UUID_KEY_SUBVOL",
+		[BTRFS_UUID_KEY_RECEIVED_SUBVOL]	= "UUID_KEY_RECEIVED_SUBVOL",
+		[BTRFS_RAID_STRIPE_KEY]			= "RAID_STRIPE",
+	};
+
+	if (key->type == 0 && key->objectid == BTRFS_FREE_SPACE_OBJECTID)
+		scnprintf(buf, buf_size, "UNTYPED");
+	else if (key_to_str[key->type])
+		scnprintf(buf, buf_size, key_to_str[key->type]);
+	else
+		scnprintf(buf, buf_size, "UNKNOWN.%d", key->type);
+}
+
 void btrfs_print_leaf(const struct extent_buffer *l)
 {
 	struct btrfs_fs_info *fs_info;
@@ -390,10 +450,14 @@ void btrfs_print_leaf(const struct extent_buffer *l)
 		   btrfs_leaf_free_space(l), btrfs_header_owner(l));
 	print_eb_refs_lock(l);
 	for (i = 0 ; i < nr ; i++) {
+		char key_buf[KEY_TYPE_BUF_SIZE];
+
 		btrfs_item_key_to_cpu(l, &key, i);
 		type = key.type;
-		pr_info("\titem %d key (%llu %u %llu) itemoff %d itemsize %d\n",
-			i, key.objectid, type, key.offset,
+		key_type_string(&key, key_buf, KEY_TYPE_BUF_SIZE);
+
+		pr_info("\titem %d key (%llu %s %llu) itemoff %d itemsize %d\n",
+			i, key.objectid, key_buf, key.offset,
 			btrfs_item_offset(l, i), btrfs_item_size(l, i));
 		switch (type) {
 		case BTRFS_INODE_ITEM_KEY:
-- 
2.47.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 00/11] btrfs: print-tree enhancements
  2025-09-15 16:37 [PATCH 00/11] btrfs: print-tree enhancements fdmanana
                   ` (10 preceding siblings ...)
  2025-09-15 16:37 ` [PATCH 11/11] btrfs: print-tree: print key types as human readable strings fdmanana
@ 2025-09-15 22:02 ` Qu Wenruo
  2025-09-16  6:46 ` Johannes Thumshirn
  12 siblings, 0 replies; 14+ messages in thread
From: Qu Wenruo @ 2025-09-15 22:02 UTC (permalink / raw)
  To: fdmanana, linux-btrfs



在 2025/9/16 02:07, fdmanana@kernel.org 写道:
> From: Filipe Manana <fdmanana@suse.com>
> 
> The following are several enhancements to the kernel print-tree
> implementation. These are motivated by debugging log tree leaves and
> apply to the type of items we can find in log trees, and having this
> makes the debugging much simpler. Details in the change logs.

Reviewed-by: Qu Wenruo <wqu@suse.com>

The extra attention to name printing (by not printing them at all) is 
pretty good.
> 
> Filipe Manana (11):
>    btrfs: print-tree: print missing fields for inode items
>    btrfs: print-tree: print more information about dir items
>    btrfs: print-tree: print dir items for dir index and xattr keys too
>    btrfs: print-tree: print information about inode ref items
>    btrfs: print-tree: print information about inode extref items

In fact this exposed a hole in tree-checker, where we didn't check inode 
extref at all.

I'll send out a fix to tree-checker so that we won't get possible 
truncated/overflowed inode extrefs.

Thanks,
Qu

>    btrfs: print-tree: print information about dir log items
>    btrfs: print-tree: print range information for extent csum items
>    btrfs: print-tree: print correct inline extent data size
>    btrfs: print-tree: print compression type for file extent items
>    btrfs: print-tree: move code for processing file extent item into helper
>    btrfs: print-tree: print key types as human readable strings
> 
>   fs/btrfs/print-tree.c | 256 ++++++++++++++++++++++++++++++++++++------
>   1 file changed, 222 insertions(+), 34 deletions(-)
> 


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 00/11] btrfs: print-tree enhancements
  2025-09-15 16:37 [PATCH 00/11] btrfs: print-tree enhancements fdmanana
                   ` (11 preceding siblings ...)
  2025-09-15 22:02 ` [PATCH 00/11] btrfs: print-tree enhancements Qu Wenruo
@ 2025-09-16  6:46 ` Johannes Thumshirn
  12 siblings, 0 replies; 14+ messages in thread
From: Johannes Thumshirn @ 2025-09-16  6:46 UTC (permalink / raw)
  To: fdmanana@kernel.org, linux-btrfs@vger.kernel.org

On 9/15/25 6:37 PM, fdmanana@kernel.org wrote:
> From: Filipe Manana <fdmanana@suse.com>
>
> The following are several enhancements to the kernel print-tree
> implementation. These are motivated by debugging log tree leaves and
> apply to the type of items we can find in log trees, and having this
> makes the debugging much simpler. Details in the change logs.
>
> Filipe Manana (11):
>    btrfs: print-tree: print missing fields for inode items
>    btrfs: print-tree: print more information about dir items
>    btrfs: print-tree: print dir items for dir index and xattr keys too
>    btrfs: print-tree: print information about inode ref items
>    btrfs: print-tree: print information about inode extref items
>    btrfs: print-tree: print information about dir log items
>    btrfs: print-tree: print range information for extent csum items
>    btrfs: print-tree: print correct inline extent data size
>    btrfs: print-tree: print compression type for file extent items
>    btrfs: print-tree: move code for processing file extent item into helper
>    btrfs: print-tree: print key types as human readable strings
>
>   fs/btrfs/print-tree.c | 256 ++++++++++++++++++++++++++++++++++++------
>   1 file changed, 222 insertions(+), 34 deletions(-)
>
Looks good,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2025-09-16  6:46 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-15 16:37 [PATCH 00/11] btrfs: print-tree enhancements fdmanana
2025-09-15 16:37 ` [PATCH 01/11] btrfs: print-tree: print missing fields for inode items fdmanana
2025-09-15 16:37 ` [PATCH 02/11] btrfs: print-tree: print more information about dir items fdmanana
2025-09-15 16:37 ` [PATCH 03/11] btrfs: print-tree: print dir items for dir index and xattr keys too fdmanana
2025-09-15 16:37 ` [PATCH 04/11] btrfs: print-tree: print information about inode ref items fdmanana
2025-09-15 16:37 ` [PATCH 05/11] btrfs: print-tree: print information about inode extref items fdmanana
2025-09-15 16:37 ` [PATCH 06/11] btrfs: print-tree: print information about dir log items fdmanana
2025-09-15 16:37 ` [PATCH 07/11] btrfs: print-tree: print range information for extent csum items fdmanana
2025-09-15 16:37 ` [PATCH 08/11] btrfs: print-tree: print correct inline extent data size fdmanana
2025-09-15 16:37 ` [PATCH 09/11] btrfs: print-tree: print compression type for file extent items fdmanana
2025-09-15 16:37 ` [PATCH 10/11] btrfs: print-tree: move code for processing file extent item into helper fdmanana
2025-09-15 16:37 ` [PATCH 11/11] btrfs: print-tree: print key types as human readable strings fdmanana
2025-09-15 22:02 ` [PATCH 00/11] btrfs: print-tree enhancements Qu Wenruo
2025-09-16  6:46 ` Johannes Thumshirn

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.