linux/fs/btrfs
Filipe Manana 2ed45c0f18 btrfs: fix race when refilling delayed refs block reserve
If we have two (or more) tasks attempting to refill the delayed refs block
reserve we can end up with the delayed block reserve being over reserved,
that is, with a reserved space greater than its size. If this happens, we
are holding to more reserved space than necessary for a while.

The race happens like this:

1) The delayed refs block reserve has a size of 8M and a reserved space of
   6M for example;

2) Task A calls btrfs_delayed_refs_rsv_refill();

3) Task B also calls btrfs_delayed_refs_rsv_refill();

4) Task A sees there's a 2M difference between the size and the reserved
   space of the delayed refs rsv, so it will reserve 2M of space by
   calling btrfs_reserve_metadata_bytes();

5) Task B also sees that 2M difference, and like task A, it reserves
   another 2M of metadata space;

6) Both task A and task B increase the reserved space of block reserve
   by 2M, by calling btrfs_block_rsv_add_bytes(), so the block reserve
   ends up with a size of 8M and a reserved space of 10M;

7) The extra, over reserved space will eventually be freed by some task
   calling btrfs_delayed_refs_rsv_release() -> btrfs_block_rsv_release()
   -> block_rsv_release_bytes(), as there we will detect the over reserve
   and release that space.

So fix this by checking if we still need to add space to the delayed refs
block reserve after reserving the metadata space, and if we don't, just
release that space immediately.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2023-09-20 20:42:08 +02:00
..
tests btrfs: tests: test invalid splitting when skipping pinned drop extent_map 2023-08-21 14:54:49 +02:00
accessors.c
accessors.h btrfs: use helper sizeof_field in struct accessors 2023-08-21 14:52:13 +02:00
acl.c
acl.h
async-thread.c
async-thread.h
backref.c btrfs: remove v0 extent handling 2023-08-21 14:54:48 +02:00
backref.h
bio.c
bio.h
block-group.c btrfs: fix race between finishing block group creation and its item update 2023-09-08 14:10:36 +02:00
block-group.h btrfs: rename add_new_free_space() to btrfs_add_new_free_space() 2023-08-21 14:52:12 +02:00
block-rsv.c btrfs: account block group tree when calculating global reserve size 2023-07-20 19:22:54 +02:00
block-rsv.h
btrfs_inode.h btrfs: reduce the number of arguments to btrfs_run_delalloc_range 2023-08-21 14:52:14 +02:00
check-integrity.c
check-integrity.h
compression.c
compression.h
ctree.c
ctree.h btrfs: fix infinite directory reads 2023-08-14 16:17:37 +02:00
defrag.c
defrag.h
delalloc-space.c
delalloc-space.h
delayed-inode.c btrfs: assert delayed node locked when removing delayed item 2023-09-08 14:20:40 +02:00
delayed-inode.h btrfs: fix infinite directory reads 2023-08-14 16:17:37 +02:00
delayed-ref.c btrfs: fix race when refilling delayed refs block reserve 2023-09-20 20:42:08 +02:00
delayed-ref.h
dev-replace.c btrfs: make find_first_extent_bit() return a boolean 2023-08-21 14:52:12 +02:00
dev-replace.h
dir-item.c
dir-item.h
discard.c
discard.h
disk-io.c btrfs: fix a compilation error if DEBUG is defined in btree_dirty_folio 2023-09-08 14:11:04 +02:00
disk-io.h btrfs: make btrfs_cleanup_fs_roots() static 2023-08-21 14:52:18 +02:00
export.c
export.h
extent-io-tree.c btrfs: make find_first_extent_bit() return a boolean 2023-08-21 14:52:12 +02:00
extent-io-tree.h btrfs: make find_first_extent_bit() return a boolean 2023-08-21 14:52:12 +02:00
extent-tree.c btrfs: remove v0 extent handling 2023-08-21 14:54:48 +02:00
extent-tree.h btrfs: wait on uncached block groups on every allocation loop 2023-08-21 14:54:47 +02:00
extent_io.c btrfs: don't clear uptodate on write errors 2023-09-13 18:41:07 +02:00
extent_io.h btrfs: zoned: introduce block group context to btrfs_eb_write_context 2023-08-21 14:52:19 +02:00
extent_map.c btrfs: fix incorrect splitting in btrfs_drop_extent_map_range 2023-08-18 14:38:10 +02:00
extent_map.h
file-item.c btrfs: scrub: avoid unnecessary csum tree search preparing stripes 2023-08-21 14:54:48 +02:00
file-item.h btrfs: scrub: avoid unnecessary csum tree search preparing stripes 2023-08-21 14:54:48 +02:00
file.c btrfs: file_remove_privs needs an exclusive lock in direct io write 2023-09-13 18:41:03 +02:00
file.h
free-space-cache.c btrfs: zoned: no longer count fresh BG region as zone unusable 2023-08-21 14:52:19 +02:00
free-space-cache.h
free-space-tree.c btrfs: rename add_new_free_space() to btrfs_add_new_free_space() 2023-08-21 14:52:12 +02:00
free-space-tree.h
fs.c
fs.h btrfs: zoned: activate metadata block group on write time 2023-08-21 14:52:19 +02:00
inode-item.c
inode-item.h
inode.c btrfs: fix race between reading a directory and adding entries to it 2023-09-14 23:24:42 +02:00
ioctl.c btrfs: release path before inode lookup during the ino lookup ioctl 2023-09-08 14:10:40 +02:00
ioctl.h
Kconfig MAINTAINERS: remove links to obsolete btrfs.wiki.kernel.org 2023-09-08 14:21:27 +02:00
locking.c
locking.h btrfs: do not block starts waiting on previous transaction commit 2023-09-08 14:10:49 +02:00
lru_cache.c
lru_cache.h
lzo.c
Makefile
messages.c btrfs: remove v0 extent handling 2023-08-21 14:54:48 +02:00
messages.h btrfs: remove v0 extent handling 2023-08-21 14:54:48 +02:00
misc.h
ordered-data.c btrfs: check for BTRFS_FS_ERROR in pending ordered assert 2023-09-08 14:10:59 +02:00
ordered-data.h
orphan.c
orphan.h
print-tree.c btrfs: remove v0 extent handling 2023-08-21 14:54:48 +02:00
print-tree.h
props.c
props.h
qgroup.c btrfs: avoid start and commit empty transaction when flushing qgroups 2023-08-21 14:52:18 +02:00
qgroup.h
raid56.c btrfs: scrub: avoid unnecessary csum tree search preparing stripes 2023-08-21 14:54:48 +02:00
raid56.h btrfs: raid56: remove unused BTRFS_RBIO_REBUILD_MISSING 2023-08-21 14:52:12 +02:00
rcu-string.h
ref-verify.c
ref-verify.h
reflink.c
reflink.h
relocation.c btrfs: remove v0 extent handling 2023-08-21 14:54:48 +02:00
relocation.h
root-tree.c
root-tree.h
scrub.c btrfs: scrub: move write back of repaired sectors to scrub_stripe_read_repair_worker() 2023-08-21 14:54:49 +02:00
scrub.h
send.c btrfs: use LIST_HEAD() to initialize the list_head 2023-08-21 14:54:46 +02:00
send.h
space-info.c btrfs: zoned: re-enable metadata over-commit for zoned mode 2023-08-21 14:52:19 +02:00
space-info.h
subpage.c
subpage.h
super.c btrfs: deprecate integrity checker feature 2023-08-21 14:52:13 +02:00
super.h
sysfs.c btrfs: sysfs: show if ACL support has been compiled in 2023-08-21 14:52:12 +02:00
sysfs.h
transaction.c btrfs: do not block starts waiting on previous transaction commit 2023-09-08 14:10:49 +02:00
transaction.h btrfs: do not block starts waiting on previous transaction commit 2023-09-08 14:10:49 +02:00
tree-checker.c for-6.5-rc5-tag 2023-08-12 13:28:55 -07:00
tree-checker.h
tree-log.c btrfs: use LIST_HEAD() to initialize the list_head 2023-08-21 14:54:46 +02:00
tree-log.h
tree-mod-log.c
tree-mod-log.h
ulist.c
ulist.h
uuid-tree.c
uuid-tree.h
verity.c btrfs: convert btrfs_read_merkle_tree_page() to use a folio 2023-09-13 18:40:54 +02:00
verity.h
volumes.c btrfs: simplify memcpy either of metadata_uuid or fsid 2023-08-21 14:54:48 +02:00
volumes.h btrfs: add a helper to read the superblock metadata_uuid 2023-08-21 14:54:48 +02:00
xattr.c
xattr.h
zlib.c
zoned.c btrfs: zoned: skip splitting and logical rewriting on pre-alloc write 2023-08-22 14:19:59 +02:00
zoned.h btrfs: zoned: reserve zones for an active metadata/system block group 2023-08-21 14:52:19 +02:00
zstd.c