diff options
author | Filipe Manana <fdmanana@suse.com> | 2024-03-22 21:23:03 +0300 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2024-05-07 22:31:02 +0300 |
commit | 5d6f0e9890ed857a0bafb7fa73c85bf49bbe1e14 (patch) | |
tree | 23da03db07d0aeb7864db24eaf13d0b6927336cf /fs/btrfs/compression.h | |
parent | 4a43d735a6028a9852e72a3ce02343942fd73c22 (diff) | |
download | linux-5d6f0e9890ed857a0bafb7fa73c85bf49bbe1e14.tar.xz |
btrfs: stop locking the source extent range during reflink
Nowadays before starting a reflink operation we do this:
1) Take the VFS lock of the inodes in exclusive mode (a rw semaphore);
2) Take the mmap lock of the inodes (struct btrfs_inode::i_mmap_lock);
3) Flush all delalloc in the source and target ranges;
4) Wait for all ordered extents in the source and target ranges to
complete;
5) Lock the source and destination ranges in the inodes' io trees.
In step 5 we lock the source range because:
1) We needed to serialize against mmap writes, but that is not needed
anymore because nowadays we do that through the inode's i_mmap_lock
(step 2). This happens since commit 8c99516a8cdd ("btrfs: exclude mmaps
while doing remap");
2) To serialize against a concurrent relocation and avoid generating
a delayed ref for an extent that was just dropped by relocation, see
commit d8b552424210 ("Btrfs: fix race between reflink/dedupe and
relocation").
Locking the source range however blocks any concurrent reads for that
range and makes test case generic/733 fail.
So instead of locking the source range during reflinks, make relocation
read lock the inode's i_mmap_lock, so that it serializes with a concurrent
reflink while still able to run concurrently with mmap writes and allow
concurrent reads too.
Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/compression.h')
0 files changed, 0 insertions, 0 deletions