Skip to content

Commit 211de93

Browse files
boryaskdave
authored andcommitted
btrfs: qgroup: convert PREALLOC to PERTRANS after record_root_in_trans
The transaction is only able to free PERTRANS reservations for a root once that root has been recorded with the TRANS tag on the roots radix tree. Therefore, until we are sure that this root will get tagged, it isn't safe to convert. Generally, this is not an issue as *some* transaction will likely tag the root before long and this reservation will get freed in that transaction, but technically it could stick around until unmount and result in a warning about leaked metadata reservation space. This path is most exercised by running the generic/269 fstest with CONFIG_BTRFS_DEBUG. Fixes: a649684 ("btrfs: fix start transaction qgroup rsv double free") CC: [email protected] # 6.6+ Reviewed-by: Qu Wenruo <[email protected]> Signed-off-by: Boris Burkov <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 71537e3 commit 211de93

File tree

1 file changed

+8
-9
lines changed

1 file changed

+8
-9
lines changed

fs/btrfs/transaction.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -745,14 +745,6 @@ start_transaction(struct btrfs_root *root, unsigned int num_items,
745745
h->reloc_reserved = reloc_reserved;
746746
}
747747

748-
/*
749-
* Now that we have found a transaction to be a part of, convert the
750-
* qgroup reservation from prealloc to pertrans. A different transaction
751-
* can't race in and free our pertrans out from under us.
752-
*/
753-
if (qgroup_reserved)
754-
btrfs_qgroup_convert_reserved_meta(root, qgroup_reserved);
755-
756748
got_it:
757749
if (!current->journal_info)
758750
current->journal_info = h;
@@ -786,8 +778,15 @@ start_transaction(struct btrfs_root *root, unsigned int num_items,
786778
* not just freed.
787779
*/
788780
btrfs_end_transaction(h);
789-
return ERR_PTR(ret);
781+
goto reserve_fail;
790782
}
783+
/*
784+
* Now that we have found a transaction to be a part of, convert the
785+
* qgroup reservation from prealloc to pertrans. A different transaction
786+
* can't race in and free our pertrans out from under us.
787+
*/
788+
if (qgroup_reserved)
789+
btrfs_qgroup_convert_reserved_meta(root, qgroup_reserved);
791790

792791
return h;
793792

0 commit comments

Comments
 (0)