linux/fs/btrfs
Filipe Manana 0a8068a3dd btrfs: make ranged full fsyncs more efficient
Commit 0c713cbab6 ("Btrfs: fix race between ranged fsync and writeback
of adjacent ranges") fixed a bug where we could end up with file extent
items in a log tree that represent file ranges that overlap due to a race
between the hole detection of a ranged full fsync and writeback for a
different file range.

The problem was solved by forcing any ranged full fsync to become a
non-ranged full fsync - setting the range start to 0 and the end offset to
LLONG_MAX. This was a simple solution because the code that detected and
marked holes was very complex, it used to be done at copy_items() and
implied several searches on the fs/subvolume tree. The drawback of that
solution was that we started to flush delalloc for the entire file and
wait for all the ordered extents to complete for ranged full fsyncs
(including ordered extents covering ranges completely outside the given
range). Fortunatelly ranged full fsyncs are not the most common case
(hopefully for most workloads).

However a later fix for detecting and marking holes was made by commit
0e56315ca1 ("Btrfs: fix missing hole after hole punching and fsync
when using NO_HOLES") and it simplified a lot the detection of holes,
and now copy_items() no longer does it and we do it in a much more simple
way at btrfs_log_holes().

This makes it now possible to simply make the code that detects holes to
operate only on the initial range and no longer need to operate on the
whole file, while also avoiding the need to flush delalloc for the entire
file and wait for ordered extents that cover ranges that don't overlap the
given range.

Another special care is that we must skip file extent items that fall
entirely outside the fsync range when copying inode items from the
fs/subvolume tree into the log tree - this is to avoid races with ordered
extent completion for extents falling outside the fsync range, which could
cause us to end up with file extent items in the log tree that have
overlapping ranges - for example if the fsync range is [1Mb, 2Mb], when
we copy inode items we could copy an extent item for the range [0, 512K],
then release the search path and before moving to the next leaf, an
ordered extent for a range of [256Kb, 512Kb] completes - this would
cause us to copy the new extent item for range [256Kb, 512Kb] into the
log tree after we have copied one for the range [0, 512Kb] - the extents
overlap, resulting in a corruption.

So this change just does these steps:

1) When the NO_HOLES feature is enabled it leaves the initial range
   intact - no longer sets it to [0, LLONG_MAX] when the full sync bit
   is set in the inode. If NO_HOLES is not enabled, always set the range
   to a full, just like before this change, to avoid missing file extent
   items representing holes after replaying the log (for both full and
   fast fsyncs);

2) Make the hole detection code to operate only on the fsync range;

3) Make the code that copies items from the fs/subvolume tree to skip
   copying file extent items that cover a range completely outside the
   range of the fsync.

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2020-03-23 17:01:56 +01:00
..
tests btrfs: rename btrfs_put_fs_root and btrfs_grab_fs_root 2020-03-23 17:01:33 +01:00
acl.c
async-thread.c Btrfs: fix crash during unmount due to race with delayed inode workers 2020-03-23 17:01:51 +01:00
async-thread.h Btrfs: fix crash during unmount due to race with delayed inode workers 2020-03-23 17:01:51 +01:00
backref.c btrfs: backref, use correct count to resolve normal data refs 2020-03-23 17:01:40 +01:00
backref.h btrfs: fiemap: preallocate ulists for btrfs_check_shared 2019-07-01 13:34:53 +02:00
block-group.c btrfs: add RCU locks around block group initialization 2020-03-23 17:01:53 +01:00
block-group.h btrfs: Move and unexport btrfs_rmap_block 2020-01-23 17:24:34 +01:00
block-rsv.c btrfs: Remove __ prefix from btrfs_block_rsv_release 2020-03-23 17:01:55 +01:00
block-rsv.h btrfs: Remove __ prefix from btrfs_block_rsv_release 2020-03-23 17:01:55 +01:00
btrfs_inode.h btrfs: introduce per-inode file extent tree 2020-03-23 17:01:24 +01:00
check-integrity.c btrfs: remove buffer_heads form super block mirror integrity checking 2020-03-23 17:01:40 +01:00
check-integrity.h btrfs: remove btrfsic_submit_bh() 2020-03-23 17:01:39 +01:00
compression.c btrfs: use larger zlib buffer for s390 hardware compression 2020-01-31 10:30:40 -08:00
compression.h btrfs: compression: remove ops pointer from workspace_manager 2019-11-18 12:46:59 +01:00
ctree.c btrfs: inline checksum name and driver definitions 2020-03-23 17:01:52 +01:00
ctree.h btrfs: add helper to get the end offset of a file extent item 2020-03-23 17:01:56 +01:00
delalloc-space.c btrfs: Remove __ prefix from btrfs_block_rsv_release 2020-03-23 17:01:55 +01:00
delalloc-space.h btrfs: migrate the delalloc space stuff to it's own home 2019-07-04 17:26:17 +02:00
delayed-inode.c btrfs: Remove __ prefix from btrfs_block_rsv_release 2020-03-23 17:01:55 +01:00
delayed-inode.h btrfs: delayed-inode: Replace zero-length array with flexible-array member 2020-03-23 17:01:53 +01:00
delayed-ref.c btrfs: Remove __ prefix from btrfs_block_rsv_release 2020-03-23 17:01:55 +01:00
delayed-ref.h btrfs: migrate the delayed refs rsv code 2019-07-04 17:26:17 +02:00
dev-replace.c btrfs: sysfs, rename device_link add/remove functions 2020-03-23 17:01:35 +01:00
dev-replace.h btrfs: add __pure attribute to functions 2019-11-18 12:46:52 +01:00
dir-item.c btrfs: remove unused parameter fs_info from btrfs_extend_item 2019-04-29 19:02:50 +02:00
discard.c btrfs: add correction to handle -1 edge case in async discard 2020-01-20 16:41:01 +01:00
discard.h btrfs: have multiple discard lists 2020-01-20 16:41:00 +01:00
disk-io.c btrfs: return void from csum_tree_block 2020-03-23 17:01:52 +01:00
disk-io.h btrfs: use the page cache for super block reading 2020-03-23 17:01:39 +01:00
export.c btrfs: export helpers for subvolume name/id resolution 2020-03-23 17:01:42 +01:00
export.h btrfs: export helpers for subvolume name/id resolution 2020-03-23 17:01:42 +01:00
extent_io.c btrfs: Don't submit any btree write bio if the fs has errors 2020-03-23 17:01:46 +01:00
extent_io.h btrfs: sink argument tree to extent_read_full_page 2020-03-23 17:01:35 +01:00
extent_map.c Btrfs: fix race between using extent maps and merging them 2020-02-12 17:16:46 +01:00
extent_map.h btrfs: remove extent_map::bdev 2019-11-18 23:43:44 +01:00
extent-io-tree.h btrfs: switch to per-transaction pinned extents 2020-03-23 17:01:38 +01:00
extent-tree.c btrfs: Remove block_rsv parameter from btrfs_drop_snapshot 2020-03-23 17:01:55 +01:00
file-item.c btrfs: add helper to get the end offset of a file extent item 2020-03-23 17:01:56 +01:00
file.c btrfs: make ranged full fsyncs more efficient 2020-03-23 17:01:56 +01:00
free-space-cache.c btrfs: simplify error handling in __btrfs_write_out_cache() 2020-03-23 17:01:43 +01:00
free-space-cache.h btrfs: have multiple discard lists 2020-01-20 16:41:00 +01:00
free-space-tree.c btrfs: rename btrfs_put_fs_root and btrfs_grab_fs_root 2020-03-23 17:01:33 +01:00
free-space-tree.h btrfs: rename btrfs_block_group_cache 2019-11-18 17:51:51 +01:00
inode-item.c btrfs: Make btrfs_find_name_in_ext_backref return struct btrfs_inode_extref 2019-09-09 14:59:16 +02:00
inode-map.c btrfs: Remove __ prefix from btrfs_block_rsv_release 2020-03-23 17:01:55 +01:00
inode-map.h
inode.c btrfs: add helper to get the end offset of a file extent item 2020-03-23 17:01:56 +01:00
ioctl.c Btrfs: move all reflink implementation code into its own file 2020-03-23 17:01:54 +01:00
Kconfig btrfs: add Kconfig dependency for BLAKE2B 2019-12-09 17:56:06 +01:00
locking.c btrfs: Implement DREW lock 2020-03-23 17:01:43 +01:00
locking.h btrfs: Implement DREW lock 2020-03-23 17:01:43 +01:00
lzo.c btrfs: compression: inline free_workspace 2019-11-18 12:46:59 +01:00
Makefile Btrfs: move all reflink implementation code into its own file 2020-03-23 17:01:54 +01:00
misc.h btrfs: add 64bit safe helper for power of two checks 2019-11-18 12:46:50 +01:00
ordered-data.c btrfs: drop argument tree from btrfs_lock_and_flush_ordered_range 2020-03-23 17:01:34 +01:00
ordered-data.h btrfs: drop argument tree from btrfs_lock_and_flush_ordered_range 2020-03-23 17:01:34 +01:00
orphan.c
print-tree.c btrfs: Remove unneeded semicolon 2020-01-20 16:40:55 +01:00
print-tree.h
props.c btrfs: Remove __ prefix from btrfs_block_rsv_release 2020-03-23 17:01:55 +01:00
props.h btrfs: delete unused function btrfs_set_prop_trans 2019-04-29 19:02:54 +02:00
qgroup.c btrfs: qgroup: Remove the unnecesaary spin lock for qgroup_rescan_running 2020-03-23 17:01:47 +01:00
qgroup.h btrfs: destroy qgroup extent records on transaction abort 2020-02-19 00:35:54 +01:00
raid56.c btrfs: use struct_size to calculate size of raid hash table 2020-03-23 17:01:44 +01:00
raid56.h btrfs: constify map parameter for nr_parity_stripes and nr_data_stripes 2019-07-01 13:34:58 +02:00
rcu-string.h btrfs: rcu-string: Replace zero-length array with flexible-array member 2020-03-23 17:01:53 +01:00
reada.c btrfs: rename btrfs_block_group_cache 2019-11-18 17:51:51 +01:00
ref-verify.c btrfs: ref-verify: fix memory leaks 2020-02-12 17:16:31 +01:00
ref-verify.h btrfs: ref-verify: Use btrfs_ref to refactor btrfs_ref_tree_mod() 2019-04-29 19:02:49 +02:00
reflink.c Btrfs: implement full reflink support for inline extents 2020-03-23 17:01:54 +01:00
reflink.h Btrfs: move all reflink implementation code into its own file 2020-03-23 17:01:54 +01:00
relocation.c btrfs: Remove block_rsv parameter from btrfs_drop_snapshot 2020-03-23 17:01:55 +01:00
root-tree.c btrfs: Remove __ prefix from btrfs_block_rsv_release 2020-03-23 17:01:55 +01:00
scrub.c btrfs: scrub: Replace zero-length array with flexible-array member 2020-03-23 17:01:54 +01:00
send.c btrfs: add helper to get the end offset of a file extent item 2020-03-23 17:01:56 +01:00
send.h
space-info.c btrfs: account ticket size at add/delete time 2020-03-23 17:01:55 +01:00
space-info.h btrfs: account ticket size at add/delete time 2020-03-23 17:01:55 +01:00
struct-funcs.c btrfs: tie extent buffer and it's token together 2019-09-09 14:59:16 +02:00
super.c btrfs: adjust message level for unrecognized mount option 2020-03-23 17:01:45 +01:00
sysfs.c btrfs: sysfs, unify handler name of devinfo/missing 2020-03-23 17:01:36 +01:00
sysfs.h btrfs: sysfs, rename device_link add/remove functions 2020-03-23 17:01:35 +01:00
transaction.c btrfs: Remove block_rsv parameter from btrfs_drop_snapshot 2020-03-23 17:01:55 +01:00
transaction.h btrfs: switch to per-transaction pinned extents 2020-03-23 17:01:38 +01:00
tree-checker.c btrfs: tree-checker: Verify location key for DIR_ITEM/DIR_INDEX 2020-01-20 16:40:56 +01:00
tree-checker.h
tree-defrag.c
tree-log.c btrfs: make ranged full fsyncs more efficient 2020-03-23 17:01:56 +01:00
tree-log.h
ulist.c
ulist.h
uuid-tree.c btrfs: bail out of uuid tree scanning if we're closing 2020-03-23 17:01:41 +01:00
volumes.c btrfs: relocation: add error injection points for cancelling balance 2020-03-23 17:01:54 +01:00
volumes.h btrfs: introduce chunk allocation policy 2020-03-23 17:01:48 +01:00
xattr.c Btrfs: fix failure to persist compression property xattr deletion on fsync 2019-06-17 16:37:17 +02:00
xattr.h
zlib.c btrfs: use larger zlib buffer for s390 hardware compression 2020-01-31 10:30:40 -08:00
zstd.c btrfs: compression: inline free_workspace 2019-11-18 12:46:59 +01:00