]> git.ipfire.org Git - thirdparty/kernel/linux.git/commit
btrfs: ensure releasing squota reserve on head refs
authorBoris Burkov <boris@bur.io>
Fri, 1 Dec 2023 21:00:13 +0000 (13:00 -0800)
committerDavid Sterba <dsterba@suse.com>
Wed, 6 Dec 2023 21:32:57 +0000 (22:32 +0100)
commite85a0adacf170634878fffcbf34b725aff3f49ed
tree02caac7c49f9d78102d52934161d57657e2b05ea
parenta86805504b88f636a6458520d85afdf0634e3c6b
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 <boris@bur.io>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/extent-tree.c
fs/btrfs/qgroup.c
fs/btrfs/qgroup.h