aboutsummaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorFilipe Manana2022-12-23 18:28:53 +0000
committerGreg Kroah-Hartman2023-01-12 12:01:56 +0100
commit427a36cf819b38d37756291b77ed9c0c6e74daf6 (patch)
tree840d0a4c36188ea0f8cd4aac2d67d273421f9833 /fs
parentacbf70d7f9cd416718ec701dfa945d5da0486fa5 (diff)
btrfs: fix off-by-one in delalloc search during lseek
commit 2f2e84ca60660402bd81d0859703567c59556e6a upstream. During lseek, when searching for delalloc in a range that represents a hole and that range has a length of 1 byte, we end up not doing the actual delalloc search in the inode's io tree, resulting in not correctly reporting the offset with data or a hole. This actually only happens when the start offset is 0 because with any other start offset we round it down by sector size. Reproducer: $ mkfs.btrfs -f /dev/sdc $ mount /dev/sdc /mnt/sdc $ xfs_io -f -c "pwrite -q 0 1" /mnt/sdc/foo $ xfs_io -c "seek -d 0" /mnt/sdc/foo Whence Result DATA EOF It should have reported an offset of 0 instead of EOF. Fix this by updating btrfs_find_delalloc_in_range() and count_range_bits() to deal with inclusive ranges properly. These functions are already supposed to work with inclusive end offsets, they just got it wrong in a couple places due to off-by-one mistakes. A test case for fstests will be added later. Reported-by: Joan Bruguera Micó <joanbrugueram@gmail.com> Link: https://lore.kernel.org/linux-btrfs/20221223020509.457113-1-joanbrugueram@gmail.com/ Fixes: b6e833567ea1 ("btrfs: make hole and data seeking a lot more efficient") CC: stable@vger.kernel.org # 6.1 Tested-by: Joan Bruguera Micó <joanbrugueram@gmail.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/extent-io-tree.c2
-rw-r--r--fs/btrfs/file.c2
2 files changed, 2 insertions, 2 deletions
diff --git a/fs/btrfs/extent-io-tree.c b/fs/btrfs/extent-io-tree.c
index 7b93719a486c..09ae0e73e680 100644
--- a/fs/btrfs/extent-io-tree.c
+++ b/fs/btrfs/extent-io-tree.c
@@ -1507,7 +1507,7 @@ u64 count_range_bits(struct extent_io_tree *tree,
u64 last = 0;
int found = 0;
- if (WARN_ON(search_end <= cur_start))
+ if (WARN_ON(search_end < cur_start))
return 0;
spin_lock(&tree->lock);
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index ed4e1c3705d0..9bef8eaa074a 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -3671,7 +3671,7 @@ bool btrfs_find_delalloc_in_range(struct btrfs_inode *inode, u64 start, u64 end,
u64 prev_delalloc_end = 0;
bool ret = false;
- while (cur_offset < end) {
+ while (cur_offset <= end) {
u64 delalloc_start;
u64 delalloc_end;
bool delalloc;