summaryrefslogtreecommitdiff
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorBoris Burkov <boris@bur.io>2023-03-29 01:45:20 +0300
committerDavid Sterba <dsterba@suse.com>2023-10-12 17:44:11 +0300
commitbd7c1ea3a302aba727a1ced9937ec84c6407724e (patch)
tree753922744491aae09f86d86c4d6f8f9e8fca1ba4 /fs/btrfs/extent-tree.c
parent5343cd9364ea26c9f4f78896a87ed1b5b5e652d9 (diff)
downloadlinux-bd7c1ea3a302aba727a1ced9937ec84c6407724e.tar.xz
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>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 865c74dffe82..8372d065aef4 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1566,6 +1566,7 @@ static int run_delayed_data_ref(struct btrfs_trans_handle *trans,
.rsv_bytes = href->reserved_bytes,
.is_data = true,
.is_inc = true,
+ .generation = trans->transid,
};
if (extent_op)
@@ -1738,6 +1739,7 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans,
.rsv_bytes = 0,
.is_data = false,
.is_inc = true,
+ .generation = trans->transid,
};
BUG_ON(!extent_op || !extent_op->update_flags);
@@ -3287,6 +3289,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
.rsv_bytes = 0,
.is_data = is_data,
.is_inc = false,
+ .generation = btrfs_extent_generation(leaf, ei),
};
/* In this branch refs == 1 */
@@ -4924,6 +4927,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
struct btrfs_squota_delta delta = {
.root = root_objectid,
.num_bytes = ins->offset,
+ .generation = trans->transid,
.rsv_bytes = 0,
.is_data = true,
.is_inc = true,