aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-log.c
diff options
context:
space:
mode:
authorBoris Burkov <[email protected]>2025-08-20 21:52:05 +0000
committerDavid Sterba <[email protected]>2025-09-02 18:45:15 +0000
commitde134cb54c3a67644ff95b1c9bffe545e752c912 (patch)
treec14992be1a73de875e41c6e06cc2fa65a4700351 /fs/btrfs/tree-log.c
parentbtrfs: avoid load/store tearing races when checking if an inode was logged (diff)
downloadkernel-de134cb54c3a67644ff95b1c9bffe545e752c912.tar.gz
kernel-de134cb54c3a67644ff95b1c9bffe545e752c912.zip
btrfs: fix squota compressed stats leak
The following workload on a squota enabled fs: btrfs subvol create mnt/subvol # ensure subvol extents get accounted sync btrfs qgroup create 1/1 mnt btrfs qgroup assign mnt/subvol 1/1 mnt btrfs qgroup delete mnt/subvol # make the cleaner thread run btrfs filesystem sync mnt sleep 1 btrfs filesystem sync mnt btrfs qgroup destroy 1/1 mnt will fail with EBUSY. The reason is that 1/1 does the quick accounting when we assign subvol to it, gaining its exclusive usage as excl and excl_cmpr. But then when we delete subvol, the decrement happens via record_squota_delta() which does not update excl_cmpr, as squotas does not make any distinction between compressed and normal extents. Thus, we increment excl_cmpr but never decrement it, and are unable to delete 1/1. The two possible fixes are to make squota always mirror excl and excl_cmpr or to make the fast accounting separately track the plain and cmpr numbers. The latter felt cleaner to me so that is what I opted for. Fixes: 1e0e9d5771c3 ("btrfs: add helper for recording simple quota deltas") CC: [email protected] # 6.12+ Reviewed-by: Qu Wenruo <[email protected]> Signed-off-by: Boris Burkov <[email protected]> Signed-off-by: David Sterba <[email protected]>
Diffstat (limited to 'fs/btrfs/tree-log.c')
0 files changed, 0 insertions, 0 deletions