Skip to content

Commit e85a0ad

Browse files
boryaskdave
authored andcommitted
btrfs: ensure releasing squota reserve on head refs
A reservation goes through a 3 step lifetime: - generated during delalloc - released/counted by ordered_extent allocation - freed by running delayed ref That third step depends on must_insert_reserved on the head ref, so the head ref with that field set owns the reservation. Once you prepare to run the head ref, must_insert_reserved is unset, which means that running the ref must free the reservation, whether or not it succeeds, or else the reservation is leaked. That results in either a risk of spurious ENOSPC if the fs stays writeable or a warning on unmount if it is readonly. The existing squota code was aware of these invariants, but missed a few cases. Improve it by adding a helper function to use in the cleanup paths and call it from the existing early returns in running delayed refs. This also simplifies btrfs_record_squota_delta and struct btrfs_quota_delta. This fixes (or at least improves the reliability of) generic/475 with "mkfs -O squota". On my machine, that test failed ~4/10 times without this patch and passed 100/100 times with it. Signed-off-by: Boris Burkov <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent a868055 commit e85a0ad

File tree

3 files changed

+46
-19
lines changed

3 files changed

+46
-19
lines changed

fs/btrfs/extent-tree.c

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,6 +1547,23 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
15471547
return ret;
15481548
}
15491549

1550+
static void free_head_ref_squota_rsv(struct btrfs_fs_info *fs_info,
1551+
struct btrfs_delayed_ref_head *href)
1552+
{
1553+
u64 root = href->owning_root;
1554+
1555+
/*
1556+
* Don't check must_insert_reserved, as this is called from contexts
1557+
* where it has already been unset.
1558+
*/
1559+
if (btrfs_qgroup_mode(fs_info) != BTRFS_QGROUP_MODE_SIMPLE ||
1560+
!href->is_data || !is_fstree(root))
1561+
return;
1562+
1563+
btrfs_qgroup_free_refroot(fs_info, root, href->reserved_bytes,
1564+
BTRFS_QGROUP_RSV_DATA);
1565+
}
1566+
15501567
static int run_delayed_data_ref(struct btrfs_trans_handle *trans,
15511568
struct btrfs_delayed_ref_head *href,
15521569
struct btrfs_delayed_ref_node *node,
@@ -1569,7 +1586,6 @@ static int run_delayed_data_ref(struct btrfs_trans_handle *trans,
15691586
struct btrfs_squota_delta delta = {
15701587
.root = href->owning_root,
15711588
.num_bytes = node->num_bytes,
1572-
.rsv_bytes = href->reserved_bytes,
15731589
.is_data = true,
15741590
.is_inc = true,
15751591
.generation = trans->transid,
@@ -1586,11 +1602,9 @@ static int run_delayed_data_ref(struct btrfs_trans_handle *trans,
15861602
flags, ref->objectid,
15871603
ref->offset, &key,
15881604
node->ref_mod, href->owning_root);
1605+
free_head_ref_squota_rsv(trans->fs_info, href);
15891606
if (!ret)
15901607
ret = btrfs_record_squota_delta(trans->fs_info, &delta);
1591-
else
1592-
btrfs_qgroup_free_refroot(trans->fs_info, delta.root,
1593-
delta.rsv_bytes, BTRFS_QGROUP_RSV_DATA);
15941608
} else if (node->action == BTRFS_ADD_DELAYED_REF) {
15951609
ret = __btrfs_inc_extent_ref(trans, node, parent, ref->root,
15961610
ref->objectid, ref->offset,
@@ -1742,7 +1756,6 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans,
17421756
struct btrfs_squota_delta delta = {
17431757
.root = href->owning_root,
17441758
.num_bytes = fs_info->nodesize,
1745-
.rsv_bytes = 0,
17461759
.is_data = false,
17471760
.is_inc = true,
17481761
.generation = trans->transid,
@@ -1774,8 +1787,10 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans,
17741787
int ret = 0;
17751788

17761789
if (TRANS_ABORTED(trans)) {
1777-
if (insert_reserved)
1790+
if (insert_reserved) {
17781791
btrfs_pin_extent(trans, node->bytenr, node->num_bytes, 1);
1792+
free_head_ref_squota_rsv(trans->fs_info, href);
1793+
}
17791794
return 0;
17801795
}
17811796

@@ -1871,6 +1886,8 @@ u64 btrfs_cleanup_ref_head_accounting(struct btrfs_fs_info *fs_info,
18711886
struct btrfs_delayed_ref_root *delayed_refs,
18721887
struct btrfs_delayed_ref_head *head)
18731888
{
1889+
u64 ret = 0;
1890+
18741891
/*
18751892
* We had csum deletions accounted for in our delayed refs rsv, we need
18761893
* to drop the csum leaves for this update from our delayed_refs_rsv.
@@ -1885,14 +1902,13 @@ u64 btrfs_cleanup_ref_head_accounting(struct btrfs_fs_info *fs_info,
18851902

18861903
btrfs_delayed_refs_rsv_release(fs_info, 0, nr_csums);
18871904

1888-
return btrfs_calc_delayed_ref_csum_bytes(fs_info, nr_csums);
1905+
ret = btrfs_calc_delayed_ref_csum_bytes(fs_info, nr_csums);
18891906
}
1890-
if (btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_SIMPLE &&
1891-
head->must_insert_reserved && head->is_data)
1892-
btrfs_qgroup_free_refroot(fs_info, head->owning_root,
1893-
head->reserved_bytes, BTRFS_QGROUP_RSV_DATA);
1907+
/* must_insert_reserved can be set only if we didn't run the head ref. */
1908+
if (head->must_insert_reserved)
1909+
free_head_ref_squota_rsv(fs_info, head);
18941910

1895-
return 0;
1911+
return ret;
18961912
}
18971913

18981914
static int cleanup_ref_head(struct btrfs_trans_handle *trans,
@@ -2033,6 +2049,12 @@ static int btrfs_run_delayed_refs_for_head(struct btrfs_trans_handle *trans,
20332049
* spin lock.
20342050
*/
20352051
must_insert_reserved = locked_ref->must_insert_reserved;
2052+
/*
2053+
* Unsetting this on the head ref relinquishes ownership of
2054+
* the rsv_bytes, so it is critical that every possible code
2055+
* path from here forward frees all reserves including qgroup
2056+
* reserve.
2057+
*/
20362058
locked_ref->must_insert_reserved = false;
20372059

20382060
extent_op = locked_ref->extent_op;
@@ -3292,7 +3314,6 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
32923314
struct btrfs_squota_delta delta = {
32933315
.root = delayed_ref_root,
32943316
.num_bytes = num_bytes,
3295-
.rsv_bytes = 0,
32963317
.is_data = is_data,
32973318
.is_inc = false,
32983319
.generation = btrfs_extent_generation(leaf, ei),
@@ -4937,7 +4958,6 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
49374958
.root = root_objectid,
49384959
.num_bytes = ins->offset,
49394960
.generation = trans->transid,
4940-
.rsv_bytes = 0,
49414961
.is_data = true,
49424962
.is_inc = true,
49434963
};

fs/btrfs/qgroup.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4661,6 +4661,17 @@ void btrfs_qgroup_destroy_extent_records(struct btrfs_transaction *trans)
46614661
*root = RB_ROOT;
46624662
}
46634663

4664+
void btrfs_free_squota_rsv(struct btrfs_fs_info *fs_info, u64 root, u64 rsv_bytes)
4665+
{
4666+
if (btrfs_qgroup_mode(fs_info) != BTRFS_QGROUP_MODE_SIMPLE)
4667+
return;
4668+
4669+
if (!is_fstree(root))
4670+
return;
4671+
4672+
btrfs_qgroup_free_refroot(fs_info, root, rsv_bytes, BTRFS_QGROUP_RSV_DATA);
4673+
}
4674+
46644675
int btrfs_record_squota_delta(struct btrfs_fs_info *fs_info,
46654676
struct btrfs_squota_delta *delta)
46664677
{
@@ -4705,8 +4716,5 @@ int btrfs_record_squota_delta(struct btrfs_fs_info *fs_info,
47054716

47064717
out:
47074718
spin_unlock(&fs_info->qgroup_lock);
4708-
if (!ret && delta->rsv_bytes)
4709-
btrfs_qgroup_free_refroot(fs_info, root, delta->rsv_bytes,
4710-
BTRFS_QGROUP_RSV_DATA);
47114719
return ret;
47124720
}

fs/btrfs/qgroup.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,6 @@ struct btrfs_squota_delta {
274274
u64 root;
275275
/* The number of bytes in the extent being counted. */
276276
u64 num_bytes;
277-
/* The number of bytes reserved for this extent. */
278-
u64 rsv_bytes;
279277
/* The generation the extent was created in. */
280278
u64 generation;
281279
/* Whether we are using or freeing the extent. */
@@ -422,6 +420,7 @@ int btrfs_qgroup_trace_subtree_after_cow(struct btrfs_trans_handle *trans,
422420
struct btrfs_root *root, struct extent_buffer *eb);
423421
void btrfs_qgroup_destroy_extent_records(struct btrfs_transaction *trans);
424422
bool btrfs_check_quota_leak(struct btrfs_fs_info *fs_info);
423+
void btrfs_free_squota_rsv(struct btrfs_fs_info *fs_info, u64 root, u64 rsv_bytes);
425424
int btrfs_record_squota_delta(struct btrfs_fs_info *fs_info,
426425
struct btrfs_squota_delta *delta);
427426

0 commit comments

Comments
 (0)