linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Qu Wenruo <quwenruo.btrfs@gmx.com>
To: Nikolay Borisov <nborisov@suse.com>, linux-btrfs@vger.kernel.org
Subject: Re: [PATCH 1/3] btrfs-progs: check/lowmem: Check and repair root generation
Date: Mon, 12 Aug 2019 13:57:31 +0800	[thread overview]
Message-ID: <105ec15f-e1ec-82c0-0e34-6681be1d4fde@gmx.com> (raw)
In-Reply-To: <e396da5b-8ae7-fc1d-5381-d0b3138bdfba@gmx.com>



On 2019/8/10 下午5:24, Qu Wenruo wrote:
>
> [...]
>>>
>>> Because we have extra transid check in
>>> btrfs_search_slot()/btrfs_cow_block().
>>>
>>> EXTENT_BAD_TRANSID is to suppress such warning.
>>
>> nod
>>
>>>
>>>>
>>>> So repair_root_generation could possibly be as simple as just linking
>>>> root->node to the fs_info->recow_ebs and leave the rest to the existing
>>>> logic?
>>>
>>> It doesn't change the root generation.
>>
>> recow_extent_buffer seems to be doing exactly the same thing
>> repair_root_generation does - findw the root item and commits the
>> transaction. What am I missing?
>
> The way it gets the root is not correct.
>
> Using header owner is not good enough for locating the tree owning the
> tree blocks.
>
> Cases like log trees and shared tree blocks (especially for cases like
> original tree got deleted) are the main corner cases where the old
> behavior can't handle.

My bad, in fact log tree won't exist in repair mode, and since it's the
tree root node, it won't be shared with other trees, so the existing
facility is completely fine with the use case.

Thanks for pointing this out!
Qu

>
> Thanks,
> Qu
>
>>
>>>
>>>>
>>>>> +
>>>>> +	ret = btrfs_search_slot(trans, root, &key, &path, 0, 1);
>>>>> +	if (ret < 0)
>>>>> +		return ret;
>>>>> +
>>>>> +	btrfs_release_path(&path);
>>>>> +	ret = btrfs_commit_transaction(trans, root);
>>>>> +	return ret;
>>>>> +}
>>>>> diff --git a/check/mode-common.h b/check/mode-common.h
>>>>> index 4c169c6e3b29..4a3abeb02c81 100644
>>>>> --- a/check/mode-common.h
>>>>> +++ b/check/mode-common.h
>>>>> @@ -155,4 +155,5 @@ static inline bool is_valid_imode(u32 imode)
>>>>>  	return true;
>>>>>  }
>>>>>
>>>>> +int repair_root_generation(struct btrfs_root *root);
>>>>>  #endif
>>>>> diff --git a/check/mode-lowmem.c b/check/mode-lowmem.c
>>>>> index a2be0e6d7034..bf3b57f5ad2d 100644
>>>>> --- a/check/mode-lowmem.c
>>>>> +++ b/check/mode-lowmem.c
>>>>> @@ -4957,6 +4957,7 @@ static int check_btrfs_root(struct btrfs_root *root, int check_all)
>>>>>  	struct btrfs_path path;
>>>>>  	struct node_refs nrefs;
>>>>>  	struct btrfs_root_item *root_item = &root->root_item;
>>>>> +	u64 super_generation = btrfs_super_generation(root->fs_info->super_copy);
>>>>>  	int ret;
>>>>>  	int level;
>>>>>  	int err = 0;
>>>>> @@ -4978,6 +4979,21 @@ static int check_btrfs_root(struct btrfs_root *root, int check_all)
>>>>>  	level = btrfs_header_level(root->node);
>>>>>  	btrfs_init_path(&path);
>>>>>
>>>>> +	if (btrfs_root_generation(root_item) > super_generation + 1) {
>>>>> +		error(
>>>>> +	"invalid root generation for root %llu, have %llu expect (0, %llu)",
>>>>> +		      root->root_key.objectid, btrfs_root_generation(root_item),
>>>>> +		      super_generation + 1);
>>>>> +		err |= INVALID_GENERATION;
>>>>> +		if (repair) {
>>>>> +			ret = repair_root_generation(root);
>>>>> +			if (!ret) {
>>>>> +				err &= ~INVALID_GENERATION;
>>>>> +				printf("Reset generation for root %llu\n",
>>>>> +					root->root_key.objectid);
>>>>> +			}
>>>>> +		}
>>>>> +	}
>>>>>  	if (btrfs_root_refs(root_item) > 0 ||
>>>>>  	    btrfs_disk_key_objectid(&root_item->drop_progress) == 0) {
>>>>>  		path.nodes[level] = root->node;
>>>>> diff --git a/check/mode-lowmem.h b/check/mode-lowmem.h
>>>>> index d2983fd12eb4..0361fb3382b1 100644
>>>>> --- a/check/mode-lowmem.h
>>>>> +++ b/check/mode-lowmem.h
>>>>> @@ -47,6 +47,7 @@
>>>>>  #define INODE_FLAGS_ERROR	(1<<23) /* Invalid inode flags */
>>>>>  #define DIR_ITEM_HASH_MISMATCH	(1<<24) /* Dir item hash mismatch */
>>>>>  #define INODE_MODE_ERROR	(1<<25) /* Bad inode mode */
>>>>> +#define INVALID_GENERATION	(1<<26)	/* Generation is too new */
>>>>>
>>>>>  /*
>>>>>   * Error bit for low memory mode check.
>>>>>
>>>

  reply	other threads:[~2019-08-12  5:58 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-09  6:53 [PATCH 0/3] btrfs-progs: Check and repair invalid root item generation Qu Wenruo
2019-08-09  6:53 ` [PATCH 1/3] btrfs-progs: check/lowmem: Check and repair root generation Qu Wenruo
2019-08-09 16:10   ` Nikolay Borisov
2019-08-10  0:30     ` Qu Wenruo
2019-08-10  6:12       ` Nikolay Borisov
2019-08-10  9:24         ` Qu Wenruo
2019-08-12  5:57           ` Qu Wenruo [this message]
2019-08-09  6:53 ` [PATCH 2/3] btrfs-progs: check/original: Check and repair root item geneartion Qu Wenruo
2019-08-09  6:53 ` [PATCH 3/3] btrfs-progs: fsck-tests: Add test case for invalid root generation Qu Wenruo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=105ec15f-e1ec-82c0-0e34-6681be1d4fde@gmx.com \
    --to=quwenruo.btrfs@gmx.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=nborisov@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).