All of lore.kernel.org
 help / color / mirror / Atom feed
From: Qu Wenruo <wqu@suse.de>
To: dsterba@suse.cz, Qu Wenruo <quwenruo.btrfs@gmx.com>,
	Qu Wenruo <wqu@suse.com>,
	linux-btrfs@vger.kernel.org
Subject: Re: [PATCH 4/6] btrfs: qgroup: Introduce per-root swapped blocks infrastructure
Date: Fri, 19 Oct 2018 17:46:28 +0800	[thread overview]
Message-ID: <63697e20-9c39-da22-437d-b43612f25d3c@suse.de> (raw)
In-Reply-To: <20181019091516.GB16290@twin.jikos.cz>


[-- Attachment #1.1: Type: text/plain, Size: 2170 bytes --]



On 2018/10/19 下午5:15, David Sterba wrote:
> On Fri, Oct 19, 2018 at 07:29:26AM +0800, Qu Wenruo wrote:
>>
>>
>> On 2018/10/19 上午12:20, David Sterba wrote:
>>> On Thu, Oct 18, 2018 at 07:17:27PM +0800, Qu Wenruo wrote:
>>>> +void btrfs_qgroup_clean_swapped_blocks(struct btrfs_root *root)
>>>> +{
>>>> +	struct btrfs_qgroup_swapped_blocks *swapped_blocks;
>>>> +	struct btrfs_qgroup_swapped_block *cur, *next;
>>>> +	int i;
>>>> +
>>>> +	swapped_blocks = &root->swapped_blocks;
>>>> +
>>>> +	spin_lock(&swapped_blocks->lock);
>>>> +	if (!swapped_blocks->swapped)
>>>> +		goto out;
>>>> +	for (i = 0; i < BTRFS_MAX_LEVEL; i++) {
>>>> +		struct rb_root *cur_root = &swapped_blocks->blocks[i];
>>>> +
>>>> +		rbtree_postorder_for_each_entry_safe(cur, next, cur_root,
>>>> +						     node) {
>>>> +			rb_erase(&cur->node, cur_root);
>>>
>>> https://elixir.bootlin.com/linux/latest/source/include/linux/rbtree.h#L141
>>>
>>> rb_erase must not be used on the same pointer that
>>> rbtree_postorder_for_each_entry_safe iterates, here it's cur.
>>
>> Oh, thanks for pointing this out.
>>
>> So we must go the old while(rb_first()) loop...
> 
> I just realized the postorder iterator can be used here. The forbidden
> pattern is
> 
> rbtree_postorder_for_each_entry_safe() {
> 	rb_erase();
> }

Did you mean some like this is possible?

rbtree_postorder_for_each_entry_safe() {
	kfree(entry);
}

If so, I still don't really believe it's OK.

For the following tree:
                          4
                       /     \
                      2       6
                    /  \     / \
                   1    3   5   7

If current entry is 2, next is 3.
And 2 get freed.
Then we go 3, to reach next we need to go back to access 2, which is
already freed, we will trigger use-after-free.

So the only correct way to free the whole rbtree is still that tried and
true while(rb_first()) loop.

Or did I miss something?

Thanks,
Qu

> 
> But you also do kfree right after the erase, and the iterator is fine
> with that and rb_erase is pointless for an entry that's being freed
> anyway.
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

  reply	other threads:[~2018-10-19  9:46 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-18 11:17 [PATCH 0/6] btrfs: qgroup: Delay subtree scan to reduce overhead Qu Wenruo
2018-10-18 11:17 ` [PATCH 1/6] btrfs: qgroup: Allow btrfs_qgroup_extent_record::old_roots unpopulated at insert time Qu Wenruo
2018-10-18 11:17 ` [PATCH 2/6] btrfs: relocation: Commit transaction before dropping btrfs_root::reloc_root Qu Wenruo
2018-10-18 11:17 ` [PATCH 3/6] btrfs: qgroup: Refactor btrfs_qgroup_trace_subtree_swap() Qu Wenruo
2018-10-18 11:17 ` [PATCH 4/6] btrfs: qgroup: Introduce per-root swapped blocks infrastructure Qu Wenruo
2018-10-18 16:20   ` David Sterba
2018-10-18 23:29     ` Qu Wenruo
2018-10-19  9:15       ` David Sterba
2018-10-19  9:46         ` Qu Wenruo [this message]
2018-10-19 10:04           ` David Sterba
2018-10-19 13:03             ` Qu Wenruo
2018-10-18 11:17 ` [PATCH 5/6] btrfs: qgroup: Use delayed subtree rescan for balance Qu Wenruo
2018-10-19 13:12   ` David Sterba
2018-10-19 13:19     ` David Sterba
2018-10-18 11:17 ` [PATCH 6/6] btrfs: qgroup: Cleanup old subtree swap code Qu Wenruo
2018-10-19 13:42 ` [PATCH 0/6] btrfs: qgroup: Delay subtree scan to reduce overhead David Sterba
2018-10-19 13:47   ` Qu Wenruo
2018-10-19 14:51   ` Qu Wenruo
2018-10-19 14:54     ` David Sterba

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=63697e20-9c39-da22-437d-b43612f25d3c@suse.de \
    --to=wqu@suse.de \
    --cc=dsterba@suse.cz \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=quwenruo.btrfs@gmx.com \
    --cc=wqu@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 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.