btrfs: qgroup: check generation when recording simple quota delta

Simple quotas count extents only from the moment the feature is enabled.
Therefore, if we do something like:

1. create subvol S
2. write F in S
3. enable quotas
4. remove F
5. write G in S

then after 3. and 4. we would expect the simple quota usage of S to be 0
(putting aside some metadata extents that might be written) and after
5., it should be the size of G plus metadata. Therefore, we need to be
able to determine whether a particular quota delta we are processing
predates simple quota enablement.

To do this, store the transaction id when quotas were enabled. In
fs_info for immediate use and in the quota status item to make it
recoverable on mount. When we see a delta, check if the generation of
the extent item is less than that of quota enablement. If so, we should
ignore the delta from this extent.

Signed-off-by: Boris Burkov <boris@bur.io>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Boris Burkov 2023-03-28 15:45:20 -07:00 committed by David Sterba
parent 5343cd9364
commit bd7c1ea3a3
6 changed files with 40 additions and 6 deletions

View file

@ -1277,6 +1277,15 @@ struct btrfs_qgroup_status_item {
* of the scan. It contains a logical address
*/
__le64 rescan;
/*
* The generation when quotas were last enabled. Used by simple quotas to
* avoid decrementing when freeing an extent that was written before
* enable.
*
* Set only if flags contain BTRFS_QGROUP_STATUS_FLAG_SIMPLE_MODE.
*/
__le64 enable_gen;
} __attribute__ ((__packed__));
struct btrfs_qgroup_info_item {