diff mbox series

[2/2] btrfs: pretty print leaked root name

Message ID 461693e5c015857e684878e99e5e65075bb97c13.1597953516.git.josef@toxicpanda.com (mailing list archive)
State New, archived
Headers show
Series Some leaked root fixes | expand

Commit Message

Josef Bacik Aug. 20, 2020, 8 p.m. UTC
I'm a actual human being so am incapable of converting u64 to s64 in my
head, so add a helper to get the pretty name of a root objectid and use
that helper to spit out the name for any special roots for leaked roots,
so I don't have to scratch my head and figure out which root I messed up
the refs for.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/disk-io.c    |  8 +++++---
 fs/btrfs/print-tree.c | 37 +++++++++++++++++++++++++++++++++++++
 fs/btrfs/print-tree.h |  1 +
 3 files changed, 43 insertions(+), 3 deletions(-)

Comments

Nikolay Borisov Aug. 21, 2020, 7:35 a.m. UTC | #1
On 20.08.20 г. 23:00 ч., Josef Bacik wrote:
> I'm a actual human being so am incapable of converting u64 to s64 in my
> head, so add a helper to get the pretty name of a root objectid and use
> that helper to spit out the name for any special roots for leaked roots,
> so I don't have to scratch my head and figure out which root I messed up
> the refs for.
> 
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> ---
>  fs/btrfs/disk-io.c    |  8 +++++---
>  fs/btrfs/print-tree.c | 37 +++++++++++++++++++++++++++++++++++++
>  fs/btrfs/print-tree.h |  1 +
>  3 files changed, 43 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
> index ac6d6fddd5f4..a7358e0f59de 100644
> --- a/fs/btrfs/disk-io.c
> +++ b/fs/btrfs/disk-io.c
> @@ -1506,11 +1506,13 @@ void btrfs_check_leaked_roots(struct btrfs_fs_info *fs_info)
>  	struct btrfs_root *root;
>  
>  	while (!list_empty(&fs_info->allocated_roots)) {
> +		const char *name = btrfs_root_name(root->root_key.objectid);
> +
>  		root = list_first_entry(&fs_info->allocated_roots,
>  					struct btrfs_root, leak_list);
> -		btrfs_err(fs_info, "leaked root %llu-%llu refcount %d",
> -			  root->root_key.objectid, root->root_key.offset,
> -			  refcount_read(&root->refs));
> +		btrfs_err(fs_info, "leaked root %s%lld-%llu refcount %d",

nit: Won't this string result in some rather awkward looking strings,
such as:

"leaked root ROOT_TREE<objectid>-<offset>..." i.e shouldn't the
(objectid,offset) pair be marked with parentheses?

> +			  name ? name : "", root->root_key.objectid,
> +			  root->root_key.offset, refcount_read(&root->refs));
>  		while (refcount_read(&root->refs) > 1)
>  			btrfs_put_root(root);
>  		btrfs_put_root(root);
> diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
> index 61f44e78e3c9..c633aec8973d 100644
> --- a/fs/btrfs/print-tree.c
> +++ b/fs/btrfs/print-tree.c
> @@ -7,6 +7,43 @@
>  #include "disk-io.h"
>  #include "print-tree.h"
>  
> +struct name_map {
> +	u64 id;
> +	const char *name;
> +};
> +
> +static const struct name_map root_map[] = {
> +	{ BTRFS_ROOT_TREE_OBJECTID,		"ROOT_TREE"		},
> +	{ BTRFS_EXTENT_TREE_OBJECTID,		"EXTENT_TREE"		},
> +	{ BTRFS_CHUNK_TREE_OBJECTID,		"CHUNK_TREE"		},
> +	{ BTRFS_DEV_TREE_OBJECTID,		"DEV_TREE"		},
> +	{ BTRFS_FS_TREE_OBJECTID,		"FS_TREE"		},
> +	{ BTRFS_ROOT_TREE_DIR_OBJECTID,		"ROOT_TREE_DIR"		},
> +	{ BTRFS_CSUM_TREE_OBJECTID,		"CSUM_TREE"		},
> +	{ BTRFS_TREE_LOG_OBJECTID,		"TREE_LOG"		},
> +	{ BTRFS_QUOTA_TREE_OBJECTID,		"QUOTA_TREE"		},
> +	{ BTRFS_TREE_RELOC_OBJECTID,		"TREE_RELOC"		},
> +	{ BTRFS_UUID_TREE_OBJECTID,		"UUID_TREE"		},
> +	{ BTRFS_FREE_SPACE_TREE_OBJECTID,	"FREE_SPACE_TREE"	},
> +	{ BTRFS_DATA_RELOC_TREE_OBJECTID,	"DATA_RELOC_TREE"	},
> +};
> +
> +const char *btrfs_root_name(u64 objectid)
> +{
> +	int i;
> +
> +	if (objectid >= BTRFS_FIRST_FREE_OBJECTID &&
> +	    objectid <= BTRFS_LAST_FREE_OBJECTID)
> +		return NULL;
> +
> +	for (i = 0; i < ARRAY_SIZE(root_map); i++) {
> +		if (root_map[i].id == objectid)
> +			return root_map[i].name;
> +	}
> +
> +	return NULL;
> +}
> +
>  static void print_chunk(struct extent_buffer *eb, struct btrfs_chunk *chunk)
>  {
>  	int num_stripes = btrfs_chunk_num_stripes(eb, chunk);
> diff --git a/fs/btrfs/print-tree.h b/fs/btrfs/print-tree.h
> index e6bb38fd75ad..dffdfa495297 100644
> --- a/fs/btrfs/print-tree.h
> +++ b/fs/btrfs/print-tree.h
> @@ -8,5 +8,6 @@
>  
>  void btrfs_print_leaf(struct extent_buffer *l);
>  void btrfs_print_tree(struct extent_buffer *c, bool follow);
> +const char *btrfs_root_name(u64 objectid);
>  
>  #endif
>
David Sterba Aug. 21, 2020, 10:13 a.m. UTC | #2
On Fri, Aug 21, 2020 at 10:35:38AM +0300, Nikolay Borisov wrote:
> 
> 
> On 20.08.20 г. 23:00 ч., Josef Bacik wrote:
> > I'm a actual human being so am incapable of converting u64 to s64 in my
> > head, so add a helper to get the pretty name of a root objectid and use
> > that helper to spit out the name for any special roots for leaked roots,
> > so I don't have to scratch my head and figure out which root I messed up
> > the refs for.
> > 
> > Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> > ---
> >  fs/btrfs/disk-io.c    |  8 +++++---
> >  fs/btrfs/print-tree.c | 37 +++++++++++++++++++++++++++++++++++++
> >  fs/btrfs/print-tree.h |  1 +
> >  3 files changed, 43 insertions(+), 3 deletions(-)
> > 
> > diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
> > index ac6d6fddd5f4..a7358e0f59de 100644
> > --- a/fs/btrfs/disk-io.c
> > +++ b/fs/btrfs/disk-io.c
> > @@ -1506,11 +1506,13 @@ void btrfs_check_leaked_roots(struct btrfs_fs_info *fs_info)
> >  	struct btrfs_root *root;
> >  
> >  	while (!list_empty(&fs_info->allocated_roots)) {
> > +		const char *name = btrfs_root_name(root->root_key.objectid);
> > +
> >  		root = list_first_entry(&fs_info->allocated_roots,
> >  					struct btrfs_root, leak_list);
> > -		btrfs_err(fs_info, "leaked root %llu-%llu refcount %d",
> > -			  root->root_key.objectid, root->root_key.offset,
> > -			  refcount_read(&root->refs));
> > +		btrfs_err(fs_info, "leaked root %s%lld-%llu refcount %d",
> 
> nit: Won't this string result in some rather awkward looking strings,
> such as:
> 
> "leaked root ROOT_TREE<objectid>-<offset>..." i.e shouldn't the
> (objectid,offset) pair be marked with parentheses?

I don't understand why need/want to print the offset here. It is from
the key.offset but for a message we should print it in an understandable
way.
Nikolay Borisov Aug. 21, 2020, 10:25 a.m. UTC | #3
On 21.08.20 г. 13:13 ч., David Sterba wrote:
> On Fri, Aug 21, 2020 at 10:35:38AM +0300, Nikolay Borisov wrote:
>>
>>
>> On 20.08.20 г. 23:00 ч., Josef Bacik wrote:
>>> I'm a actual human being so am incapable of converting u64 to s64 in my
>>> head, so add a helper to get the pretty name of a root objectid and use
>>> that helper to spit out the name for any special roots for leaked roots,
>>> so I don't have to scratch my head and figure out which root I messed up
>>> the refs for.
>>>
>>> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
>>> ---
>>>  fs/btrfs/disk-io.c    |  8 +++++---
>>>  fs/btrfs/print-tree.c | 37 +++++++++++++++++++++++++++++++++++++
>>>  fs/btrfs/print-tree.h |  1 +
>>>  3 files changed, 43 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
>>> index ac6d6fddd5f4..a7358e0f59de 100644
>>> --- a/fs/btrfs/disk-io.c
>>> +++ b/fs/btrfs/disk-io.c
>>> @@ -1506,11 +1506,13 @@ void btrfs_check_leaked_roots(struct btrfs_fs_info *fs_info)
>>>  	struct btrfs_root *root;
>>>  
>>>  	while (!list_empty(&fs_info->allocated_roots)) {
>>> +		const char *name = btrfs_root_name(root->root_key.objectid);
>>> +
>>>  		root = list_first_entry(&fs_info->allocated_roots,
>>>  					struct btrfs_root, leak_list);
>>> -		btrfs_err(fs_info, "leaked root %llu-%llu refcount %d",
>>> -			  root->root_key.objectid, root->root_key.offset,
>>> -			  refcount_read(&root->refs));
>>> +		btrfs_err(fs_info, "leaked root %s%lld-%llu refcount %d",
>>
>> nit: Won't this string result in some rather awkward looking strings,
>> such as:
>>
>> "leaked root ROOT_TREE<objectid>-<offset>..." i.e shouldn't the
>> (objectid,offset) pair be marked with parentheses?
> 
> I don't understand why need/want to print the offset here. It is from
> the key.offset but for a message we should print it in an understandable
> way.

According to the dev docs:

btrfs_key.offset = either 0 if objectid is one of the
BTRFS_*_TREE_OBJECTID defines or if a subvolume and not a snapshot, or
if a snapshot the transaction id when this snapshot was created.



So it doesn't have a human-readable value either ways.
>
Josef Bacik Aug. 21, 2020, 2 p.m. UTC | #4
On 8/21/20 6:13 AM, David Sterba wrote:
> On Fri, Aug 21, 2020 at 10:35:38AM +0300, Nikolay Borisov wrote:
>>
>>
>> On 20.08.20 г. 23:00 ч., Josef Bacik wrote:
>>> I'm a actual human being so am incapable of converting u64 to s64 in my
>>> head, so add a helper to get the pretty name of a root objectid and use
>>> that helper to spit out the name for any special roots for leaked roots,
>>> so I don't have to scratch my head and figure out which root I messed up
>>> the refs for.
>>>
>>> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
>>> ---
>>>   fs/btrfs/disk-io.c    |  8 +++++---
>>>   fs/btrfs/print-tree.c | 37 +++++++++++++++++++++++++++++++++++++
>>>   fs/btrfs/print-tree.h |  1 +
>>>   3 files changed, 43 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
>>> index ac6d6fddd5f4..a7358e0f59de 100644
>>> --- a/fs/btrfs/disk-io.c
>>> +++ b/fs/btrfs/disk-io.c
>>> @@ -1506,11 +1506,13 @@ void btrfs_check_leaked_roots(struct btrfs_fs_info *fs_info)
>>>   	struct btrfs_root *root;
>>>   
>>>   	while (!list_empty(&fs_info->allocated_roots)) {
>>> +		const char *name = btrfs_root_name(root->root_key.objectid);
>>> +
>>>   		root = list_first_entry(&fs_info->allocated_roots,
>>>   					struct btrfs_root, leak_list);
>>> -		btrfs_err(fs_info, "leaked root %llu-%llu refcount %d",
>>> -			  root->root_key.objectid, root->root_key.offset,
>>> -			  refcount_read(&root->refs));
>>> +		btrfs_err(fs_info, "leaked root %s%lld-%llu refcount %d",
>>
>> nit: Won't this string result in some rather awkward looking strings,
>> such as:
>>
>> "leaked root ROOT_TREE<objectid>-<offset>..." i.e shouldn't the
>> (objectid,offset) pair be marked with parentheses?
> 
> I don't understand why need/want to print the offset here. It is from
> the key.offset but for a message we should print it in an understandable
> way.
> 

The offset matters for the TREE_RELOC roots, because it's the object id 
of the fs root that the reloc root refers to.  Thanks,

Josef
David Sterba Aug. 24, 2020, 11:30 a.m. UTC | #5
On Fri, Aug 21, 2020 at 10:00:35AM -0400, Josef Bacik wrote:
> On 8/21/20 6:13 AM, David Sterba wrote:
> > On Fri, Aug 21, 2020 at 10:35:38AM +0300, Nikolay Borisov wrote:
> >>>   		root = list_first_entry(&fs_info->allocated_roots,
> >>>   					struct btrfs_root, leak_list);
> >>> -		btrfs_err(fs_info, "leaked root %llu-%llu refcount %d",
> >>> -			  root->root_key.objectid, root->root_key.offset,
> >>> -			  refcount_read(&root->refs));
> >>> +		btrfs_err(fs_info, "leaked root %s%lld-%llu refcount %d",
> >>
> >> nit: Won't this string result in some rather awkward looking strings,
> >> such as:
> >>
> >> "leaked root ROOT_TREE<objectid>-<offset>..." i.e shouldn't the
> >> (objectid,offset) pair be marked with parentheses?
> > 
> > I don't understand why need/want to print the offset here. It is from
> > the key.offset but for a message we should print it in an understandable
> > way.
> 
> The offset matters for the TREE_RELOC roots, because it's the object id 
> of the fs root that the reloc root refers to.  Thanks,

Ok, that makes sense to print, though printing it as offset=... looks
confusing. Could it be rephrased to refer to the fs tree and reloc tree?
David Sterba Aug. 24, 2020, 12:46 p.m. UTC | #6
On Fri, Aug 21, 2020 at 10:35:38AM +0300, Nikolay Borisov wrote:
> 
> 
> On 20.08.20 г. 23:00 ч., Josef Bacik wrote:
> > I'm a actual human being so am incapable of converting u64 to s64 in my
> > head, so add a helper to get the pretty name of a root objectid and use
> > that helper to spit out the name for any special roots for leaked roots,
> > so I don't have to scratch my head and figure out which root I messed up
> > the refs for.
> > 
> > Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> > ---
> >  fs/btrfs/disk-io.c    |  8 +++++---
> >  fs/btrfs/print-tree.c | 37 +++++++++++++++++++++++++++++++++++++
> >  fs/btrfs/print-tree.h |  1 +
> >  3 files changed, 43 insertions(+), 3 deletions(-)
> > 
> > diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
> > index ac6d6fddd5f4..a7358e0f59de 100644
> > --- a/fs/btrfs/disk-io.c
> > +++ b/fs/btrfs/disk-io.c
> > @@ -1506,11 +1506,13 @@ void btrfs_check_leaked_roots(struct btrfs_fs_info *fs_info)
> >  	struct btrfs_root *root;
> >  
> >  	while (!list_empty(&fs_info->allocated_roots)) {
> > +		const char *name = btrfs_root_name(root->root_key.objectid);
> > +
> >  		root = list_first_entry(&fs_info->allocated_roots,
> >  					struct btrfs_root, leak_list);
> > -		btrfs_err(fs_info, "leaked root %llu-%llu refcount %d",
> > -			  root->root_key.objectid, root->root_key.offset,
> > -			  refcount_read(&root->refs));
> > +		btrfs_err(fs_info, "leaked root %s%lld-%llu refcount %d",
> 
> nit: Won't this string result in some rather awkward looking strings,
> such as:
> 
> "leaked root ROOT_TREE<objectid>-<offset>..." i.e shouldn't the
> (objectid,offset) pair be marked with parentheses?

We need to print either string name or value, and in one go. Unlike
in progs, I'd rather avoid split stings in kernel and using
pr_cont/KERN_CONT.

The option is see is to supply a buffer to the pretty printer that would
be used in case we need the numerical id. Like:

	while (allocated_roots) {
		char root_name[24];

		...
		btrfs_err(..., "leaked root %s ...",
			get_root_name(id, root_name));
	}

where

	char *get_root_name(u64 id, char *buf) {
		if (numeric root) {
			sprintf(buf, "%llu", ud);
			return buf;
		}
		return <root name from the table>;
	}
diff mbox series

Patch

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index ac6d6fddd5f4..a7358e0f59de 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1506,11 +1506,13 @@  void btrfs_check_leaked_roots(struct btrfs_fs_info *fs_info)
 	struct btrfs_root *root;
 
 	while (!list_empty(&fs_info->allocated_roots)) {
+		const char *name = btrfs_root_name(root->root_key.objectid);
+
 		root = list_first_entry(&fs_info->allocated_roots,
 					struct btrfs_root, leak_list);
-		btrfs_err(fs_info, "leaked root %llu-%llu refcount %d",
-			  root->root_key.objectid, root->root_key.offset,
-			  refcount_read(&root->refs));
+		btrfs_err(fs_info, "leaked root %s%lld-%llu refcount %d",
+			  name ? name : "", root->root_key.objectid,
+			  root->root_key.offset, refcount_read(&root->refs));
 		while (refcount_read(&root->refs) > 1)
 			btrfs_put_root(root);
 		btrfs_put_root(root);
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index 61f44e78e3c9..c633aec8973d 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -7,6 +7,43 @@ 
 #include "disk-io.h"
 #include "print-tree.h"
 
+struct name_map {
+	u64 id;
+	const char *name;
+};
+
+static const struct name_map root_map[] = {
+	{ BTRFS_ROOT_TREE_OBJECTID,		"ROOT_TREE"		},
+	{ BTRFS_EXTENT_TREE_OBJECTID,		"EXTENT_TREE"		},
+	{ BTRFS_CHUNK_TREE_OBJECTID,		"CHUNK_TREE"		},
+	{ BTRFS_DEV_TREE_OBJECTID,		"DEV_TREE"		},
+	{ BTRFS_FS_TREE_OBJECTID,		"FS_TREE"		},
+	{ BTRFS_ROOT_TREE_DIR_OBJECTID,		"ROOT_TREE_DIR"		},
+	{ BTRFS_CSUM_TREE_OBJECTID,		"CSUM_TREE"		},
+	{ BTRFS_TREE_LOG_OBJECTID,		"TREE_LOG"		},
+	{ BTRFS_QUOTA_TREE_OBJECTID,		"QUOTA_TREE"		},
+	{ BTRFS_TREE_RELOC_OBJECTID,		"TREE_RELOC"		},
+	{ BTRFS_UUID_TREE_OBJECTID,		"UUID_TREE"		},
+	{ BTRFS_FREE_SPACE_TREE_OBJECTID,	"FREE_SPACE_TREE"	},
+	{ BTRFS_DATA_RELOC_TREE_OBJECTID,	"DATA_RELOC_TREE"	},
+};
+
+const char *btrfs_root_name(u64 objectid)
+{
+	int i;
+
+	if (objectid >= BTRFS_FIRST_FREE_OBJECTID &&
+	    objectid <= BTRFS_LAST_FREE_OBJECTID)
+		return NULL;
+
+	for (i = 0; i < ARRAY_SIZE(root_map); i++) {
+		if (root_map[i].id == objectid)
+			return root_map[i].name;
+	}
+
+	return NULL;
+}
+
 static void print_chunk(struct extent_buffer *eb, struct btrfs_chunk *chunk)
 {
 	int num_stripes = btrfs_chunk_num_stripes(eb, chunk);
diff --git a/fs/btrfs/print-tree.h b/fs/btrfs/print-tree.h
index e6bb38fd75ad..dffdfa495297 100644
--- a/fs/btrfs/print-tree.h
+++ b/fs/btrfs/print-tree.h
@@ -8,5 +8,6 @@ 
 
 void btrfs_print_leaf(struct extent_buffer *l);
 void btrfs_print_tree(struct extent_buffer *c, bool follow);
+const char *btrfs_root_name(u64 objectid);
 
 #endif