Skip to content

Commit 609d993

Browse files
fdmananakdave
authored andcommitted
btrfs: fix qgroup record leaks when using simple quotas
When using simple quotas we are not supposed to allocate qgroup records when adding delayed references. However we allocate them if either mode of quotas is enabled (the new simple one or the old one), but then we never free them because running the accounting, which frees the records, is only run when using the old quotas (at btrfs_qgroup_account_extents()), resulting in a memory leak of the records allocated when adding delayed references. Fix this by allocating the records only if the old quotas mode is enabled. Also fix btrfs_qgroup_trace_extent_nolock() to return 1 if the old quotas mode is not enabled - meaning the caller has to free the record. Fixes: 182940f ("btrfs: qgroup: add new quota mode for simple quotas") Reported-by: syzbot+d3ddc6dcc6386dea398b@syzkaller.appspotmail.com Link: https://lore.kernel.org/linux-btrfs/00000000000004769106097f9a34@google.com/ Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 6c8e69e commit 609d993

2 files changed

Lines changed: 3 additions & 3 deletions

File tree

fs/btrfs/delayed-ref.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,7 +1041,7 @@ int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans,
10411041
return -ENOMEM;
10421042
}
10431043

1044-
if (btrfs_qgroup_enabled(fs_info) && !generic_ref->skip_qgroup) {
1044+
if (btrfs_qgroup_full_accounting(fs_info) && !generic_ref->skip_qgroup) {
10451045
record = kzalloc(sizeof(*record), GFP_NOFS);
10461046
if (!record) {
10471047
kmem_cache_free(btrfs_delayed_tree_ref_cachep, ref);
@@ -1144,7 +1144,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans,
11441144
return -ENOMEM;
11451145
}
11461146

1147-
if (btrfs_qgroup_enabled(fs_info) && !generic_ref->skip_qgroup) {
1147+
if (btrfs_qgroup_full_accounting(fs_info) && !generic_ref->skip_qgroup) {
11481148
record = kzalloc(sizeof(*record), GFP_NOFS);
11491149
if (!record) {
11501150
kmem_cache_free(btrfs_delayed_data_ref_cachep, ref);

fs/btrfs/qgroup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1888,7 +1888,7 @@ int btrfs_qgroup_trace_extent_nolock(struct btrfs_fs_info *fs_info,
18881888
u64 bytenr = record->bytenr;
18891889

18901890
if (!btrfs_qgroup_full_accounting(fs_info))
1891-
return 0;
1891+
return 1;
18921892

18931893
lockdep_assert_held(&delayed_refs->lock);
18941894
trace_btrfs_qgroup_trace_extent(fs_info, record);

0 commit comments

Comments
 (0)