Source
x
* transaction committing, but not now as qgroup accounting will be wrong again.
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2014 Facebook. All rights reserved.
*/
/*
* Btrfs qgroup overview
*
* Btrfs qgroup splits into 3 main part:
* 1) Reserve
* Reserve metadata/data space for incoming operations
* Affect how qgroup limit works
*
* 2) Trace
* Tell btrfs qgroup to trace dirty extents.
*
* Dirty extents including:
* - Newly allocated extents
* - Extents going to be deleted (in this trans)
* - Extents whose owner is going to be modified
*
* This is the main part affects whether qgroup numbers will stay
* consistent.
* Btrfs qgroup can trace clean extents and won't cause any problem,
* but it will consume extra CPU time, it should be avoided if possible.
*
* 3) Account
* Btrfs qgroup will updates its numbers, based on dirty extents traced
* in previous step.
*
* Normally at qgroup rescan and transaction commit time.
*/
/*
* Special performance optimization for balance.
*
* For balance, we need to swap subtree of subvolume and reloc trees.
* In theory, we need to trace all subtree blocks of both subvolume and reloc
* trees, since their owner has changed during such swap.
*
* However since balance has ensured that both subtrees are containing the
* same contents and have the same tree structures, such swap won't cause
* qgroup number change.
*
* But there is a race window between subtree swap and transaction commit,
* during that window, if we increase/decrease tree level or merge/split tree
* blocks, we still need to trace the original subtrees.
*
* So for balance, we use a delayed subtree tracing, whose workflow is:
*
* 1) Record the subtree root block get swapped.
*
* During subtree swap:
* O = Old tree blocks
* N = New tree blocks
* reloc tree subvolume tree X
* Root Root
* / \ / \
* NA OB OA OB
* / | | \ / | | \
* NC ND OE OF OC OD OE OF
*
* In this case, NA and OA are going to be swapped, record (NA, OA) into
* subvolume tree X.
*
* 2) After subtree swap.
* reloc tree subvolume tree X
* Root Root
* / \ / \
* OA OB NA OB
* / | | \ / | | \
* OC OD OE OF NC ND OE OF
*
* 3a) COW happens for OB
* If we are going to COW tree block OB, we check OB's bytenr against
* tree X's swapped_blocks structure.
* If it doesn't fit any, nothing will happen.
*
* 3b) COW happens for NA
* Check NA's bytenr against tree X's swapped_blocks, and get a hit.
* Then we do subtree scan on both subtrees OA and NA.
* Resulting 6 tree blocks to be scanned (OA, OC, OD, NA, NC, ND).
*
* Then no matter what we do to subvolume tree X, qgroup numbers will