Skip to content

Commit 2f2e84c

Browse files
fdmananakdave
authored andcommitted
btrfs: fix off-by-one in delalloc search during lseek
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ó <[email protected]> Link: https://lore.kernel.org/linux-btrfs/[email protected]/ Fixes: b6e8335 ("btrfs: make hole and data seeking a lot more efficient") CC: [email protected] # 6.1 Tested-by: Joan Bruguera Micó <[email protected]> Signed-off-by: Filipe Manana <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 1d854e4 commit 2f2e84c

File tree

2 files changed

+2
-2
lines changed

2 files changed

+2
-2
lines changed

fs/btrfs/extent-io-tree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1551,7 +1551,7 @@ u64 count_range_bits(struct extent_io_tree *tree,
15511551
u64 last = 0;
15521552
int found = 0;
15531553

1554-
if (WARN_ON(search_end <= cur_start))
1554+
if (WARN_ON(search_end < cur_start))
15551555
return 0;
15561556

15571557
spin_lock(&tree->lock);

fs/btrfs/file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3354,7 +3354,7 @@ bool btrfs_find_delalloc_in_range(struct btrfs_inode *inode, u64 start, u64 end,
33543354
bool search_io_tree = true;
33553355
bool ret = false;
33563356

3357-
while (cur_offset < end) {
3357+
while (cur_offset <= end) {
33583358
u64 delalloc_start;
33593359
u64 delalloc_end;
33603360
bool delalloc;

0 commit comments

Comments
 (0)