From: Qu Wenruo <quwenruo.btrfs@gmx.com>
To: Su Yue <suy.fnst@cn.fujitsu.com>, Su Yue <Damenly_Su@gmx.com>,
linux-btrfs@vger.kernel.org
Subject: Re: [PATCH v3 5/7] btrfs-progs: lowmem: do missing check of last item after check_inode_item()
Date: Tue, 18 Sep 2018 16:15:57 +0800 [thread overview]
Message-ID: <85c57362-2e1b-3d07-edd5-74d0750c8be3@gmx.com> (raw)
In-Reply-To: <7c713106-36a9-95a3-3648-80e67d4f5ee6@cn.fujitsu.com>
On 2018/9/18 下午4:01, Su Yue wrote:
>
>
> On 9/18/18 1:32 PM, Qu Wenruo wrote:
>>
>>
>> On 2018/9/17 下午9:24, Su Yue wrote:
>>>
>>>
>>> On 2018/9/17 8:53 PM, Qu Wenruo wrote:
>>>>
>>>>
>>>> On 2018/9/17 下午3:28, Su Yue wrote:
>>>>> After call of check_inode_item(), path may point to the last unchecked
>>>>> slot of the leaf. The outer walk_up_tree() always treats the position
>>>>> as checked slot then skips to the next. The last item will never be
>>>>> checked.
>>>>>
>>>>> While checking backrefs, path passed to walk_up_tree() always
>>>>> points to a checked slot.
>>>>> While checking fs trees, path passed to walk_up_tree() always
>>>>> points to an unchecked slot.
>>>>
>>>> Can we unify this behavior?
>>>> I has considered in three ways:
>>> 1) Change logical of the process_one_leaf. After it returns, path
>>> points to the next slot checked.
>>> To unify it, we can use saved key but will cost one search_slot time
>>> during serval nodes(>=1). Or call btrfs_previous_item() after every time
>>> check_inode_items() returns.
>>>
>>> But why? why should we cost some time to swing the path. So I
>>> abandoned 1).
>>>
>>> 2) Change logical of the check_leaf_items(). What does the function
>>> is just traverse all items then returns, which seems quite natural.
>>> So I abandoned it.
>>
>> Well, this can also be interpreted as "it's a pretty good place to
>> change the behavior".
>>
>> IMHO, since check_leaf_items() are just really simple hub functions, it
>> will just need a btrfs_next_item() in its out: tag.
>>
> After sometime thinking, sorry, the idea should not work as expected.
> In fact, backrefs check and fs check walk a little differently.
Just as discussed offline, unfortunately that's the case.
>
> Backrefs check always do walk nodes one by one, never skip any nodes.
> Fs check will try to skip shared nodes to speed up
Exactly.
>
> While checking backrefs with your idea,
> If the tree has many levels.
> Assume before calling btrfs_next_item:
> path->slots[0] points to the one past of the last item.
> path->slots[1] points to the last slot of nodes[1].
> path->slots[2] points to the last slot of nodes[2].
> path->slots[3] points to the one *before* last slot of nodes[3].
>
> After btrfs_next_item():
> path->slots[0] points to the first item of another leaf.
> path->slots[1] points to the first item of another node.
> path->slots[2] points to the first item of another node.
> path->slots[3] points to the a slot of *old* nodes[3].
These info is pretty useful, please consider include them in next version.
It's not that obvious from the code.
And now your patch makes sense.
Thanks,
Qu
>
> Then walk_up_tree() is in, it thinks the slot is unchecked then
> returns with *level=0. Then walk_down_tree() just walk from level
> to leaf.
> Backrefs of new nodes[1,2] will never be checked, the most
> obvious negative effect is inaccurate account info.
> Although we can do check is slot the first in walk_up_tree(),
> it's a magic and worse than this patch.
>
> Thanks,
> Su
>
>> By that we can unify the behavior of them to all points to the next
>> *unchecked* slot.
>> And no need for the extra parameter.
>>
>> Thanks,
>> Qu
>>
>>>
>>>
>>> 3) It's what the patch does. The extra argument may seems strange,
>>> I preferred to this way.
>>>
>>> Maybe we can do something after check_leaf_items() returns, is it
>>> acceptable? I have no idea.
>>>
>>> Thanks,
>>> Su
>>>
>>>> E.g, always points to an unchecked slot.
>>>>
>>>> It would make things easier and no need for the extra parameter.
>>>>
>>>> Thanks,
>>>> Qu
>>>>
>>>>>
>>>>> Solution:
>>>>> Add an argument @is_checked to walk_up_tree() to decide whether
>>>>> to skip current slot.
>>>>>
>>>>> Fixes: 5e2dc770471b ("btrfs-progs: check: skip shared node or leaf
>>>>> check for low_memory mode")
>>>>> Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
>>>>> ---
>>>>> check/mode-lowmem.c | 37 +++++++++++++++++++++++++++++++++----
>>>>> 1 file changed, 33 insertions(+), 4 deletions(-)
>>>>>
>>>>> diff --git a/check/mode-lowmem.c b/check/mode-lowmem.c
>>>>> index db44456fd85b..612e5e28e45b 100644
>>>>> --- a/check/mode-lowmem.c
>>>>> +++ b/check/mode-lowmem.c
>>>>> @@ -4597,22 +4597,38 @@ static int walk_down_tree(struct btrfs_root
>>>>> *root, struct btrfs_path *path,
>>>>> return err;
>>>>> }
>>>>> +/*
>>>>> + * Walk up throuh the path. Make path point to next slot to be
>>>>> checked.
>>>>> + * walk_down_tree() should be called after this function.
>>>>> + *
>>>>> + * @root: root of the tree
>>>>> + * @path: will point to next slot to check for walk_down_tree()
>>>>> + * @level: returns with level of next node to be checked
>>>>> + * @is_checked: means is the current node checked or not
>>>>> + * if false, the slot is unchecked, do not increase the slot
>>>>> + * if true, means increase the slot of the current node
>>>>> + *
>>>>> + * Returns 0 means success.
>>>>> + * Returns >0 means the whole loop of walk up/down should be broken.
>>>>> + */
>>>>> static int walk_up_tree(struct btrfs_root *root, struct btrfs_path
>>>>> *path,
>>>>> - int *level)
>>>>> + int *level, bool is_checked)
>>>>> {
>>>>> int i;
>>>>> struct extent_buffer *leaf;
>>>>> + int skip_cur =s_checked ? 1 : 0;
>>>>> for (i =level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i];
>>>>> i++) {
>>>>> leaf =ath->nodes[i];
>>>>> - if (path->slots[i] + 1 < btrfs_header_nritems(leaf)) {
>>>>> - path->slots[i]++;
>>>>> + if (path->slots[i] + skip_cur < btrfs_header_nritems(leaf)) {
>>>>> + path->slots[i] +=kip_cur;
>>>>> *level =;
>>>>> return 0;
>>>>> }
>>>>> free_extent_buffer(path->nodes[*level]);
>>>>> path->nodes[*level] =ULL;
>>>>> *level = + 1;
>>>>> + skip_cur =;
>>>>> }
>>>>> return 1;
>>>>> }
>>>>> @@ -4815,7 +4831,20 @@ static int check_btrfs_root(struct btrfs_root
>>>>> *root, int check_all)
>>>>> break;
>>>>> }
>>>>> - ret =alk_up_tree(root, &path, &level);
>>>>> + /*
>>>>> + * The logical of walk trees are shared between backrefs
>>>>> + * check and fs trees check.
>>>>> + * In checking backrefs(check_all is true), after
>>>>> + * check_leaf_items() returns, path points to
>>>>> + * last checked item.
>>>>> + * In checking fs roots(check_all is false), after
>>>>> + * process_one_leaf() returns, path points to unchecked item.
>>>>> + *
>>>>> + * walk_up_tree() is reponsible to make path point to next
>>>>> + * slot to be checked, above case is handled in
>>>>> + * walk_up_tree().
>>>>> + */
>>>>> + ret =alk_up_tree(root, &path, &level, check_all);
>>>>> if (ret !=) {
>>>>> /* Normal exit, reset ret to err */
>>>>> ret =rr;
>>>>>
>>
>>
>
>
next prev parent reply other threads:[~2018-09-18 13:47 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-17 7:28 [PATCH v3 0/7] btrfs-progs: lowmem: bug fixes and inode_extref repair Su Yue
2018-09-17 7:28 ` [PATCH v3 1/7] btrfs-progs: adjust arguments of btrfs_lookup_inode_extref() Su Yue
2018-09-17 7:28 ` [PATCH v3 2/7] btrfs-progs: make btrfs_unlink() lookup inode_extref Su Yue
2018-09-17 7:28 ` [PATCH v3 3/7] btrfs-progs: lowmem check: find dir_item by di_key in check_dir_item() Su Yue
2018-09-17 12:47 ` Qu Wenruo
2018-09-17 7:28 ` [PATCH v3 4/7] btrfs-progs: lowmem: search key of root again after check_fs_root() after repair Su Yue
2018-09-17 12:51 ` Qu Wenruo
2018-09-17 12:55 ` Su Yue
2018-09-17 13:03 ` Qu Wenruo
2018-09-17 13:13 ` Nikolay Borisov
2018-09-17 7:28 ` [PATCH v3 5/7] btrfs-progs: lowmem: do missing check of last item after check_inode_item() Su Yue
2018-09-17 12:53 ` Qu Wenruo
2018-09-17 13:24 ` Su Yue
2018-09-18 5:32 ` Qu Wenruo
2018-09-18 8:01 ` Su Yue
2018-09-18 8:15 ` Qu Wenruo [this message]
2018-09-17 7:28 ` [PATCH v3 6/7] btrfs-progs: lowmem: optimization and repair for check_inode_extref() Su Yue
2018-09-17 13:00 ` Qu Wenruo
2018-09-17 15:25 ` Nikolay Borisov
2018-09-17 7:28 ` [PATCH v3 7/7] btrfs-progs: fsck-tests: add test case inode_extref without dir_item and dir_index Su Yue
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=85c57362-2e1b-3d07-edd5-74d0750c8be3@gmx.com \
--to=quwenruo.btrfs@gmx.com \
--cc=Damenly_Su@gmx.com \
--cc=linux-btrfs@vger.kernel.org \
--cc=suy.fnst@cn.fujitsu.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).