mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 13:55:32 +00:00
Btrfs: fix stop searching test in replace_one_extent
replace_one_extent searches tree leaves for references to a given extent. It stops searching if it goes beyond the last possible position. The last possible position is computed by adding the starting offset of a found file extent to the full size of the extent. The code uses physical size of the extent as the full size. This is incorrect when compression is used. The fix is get the full size from ram_bytes field of file extent item. Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
This commit is contained in:
parent
95029d7d59
commit
86288a198d
1 changed files with 7 additions and 6 deletions
|
@ -4440,7 +4440,7 @@ static noinline int replace_one_extent(struct btrfs_trans_handle *trans,
|
|||
u64 lock_end = 0;
|
||||
u64 num_bytes;
|
||||
u64 ext_offset;
|
||||
u64 first_pos;
|
||||
u64 search_end = (u64)-1;
|
||||
u32 nritems;
|
||||
int nr_scaned = 0;
|
||||
int extent_locked = 0;
|
||||
|
@ -4448,7 +4448,6 @@ static noinline int replace_one_extent(struct btrfs_trans_handle *trans,
|
|||
int ret;
|
||||
|
||||
memcpy(&key, leaf_key, sizeof(key));
|
||||
first_pos = INT_LIMIT(loff_t) - extent_key->offset;
|
||||
if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS) {
|
||||
if (key.objectid < ref_path->owner_objectid ||
|
||||
(key.objectid == ref_path->owner_objectid &&
|
||||
|
@ -4497,7 +4496,7 @@ static noinline int replace_one_extent(struct btrfs_trans_handle *trans,
|
|||
if ((key.objectid > ref_path->owner_objectid) ||
|
||||
(key.objectid == ref_path->owner_objectid &&
|
||||
key.type > BTRFS_EXTENT_DATA_KEY) ||
|
||||
(key.offset >= first_pos + extent_key->offset))
|
||||
key.offset >= search_end)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4530,8 +4529,10 @@ static noinline int replace_one_extent(struct btrfs_trans_handle *trans,
|
|||
num_bytes = btrfs_file_extent_num_bytes(leaf, fi);
|
||||
ext_offset = btrfs_file_extent_offset(leaf, fi);
|
||||
|
||||
if (first_pos > key.offset - ext_offset)
|
||||
first_pos = key.offset - ext_offset;
|
||||
if (search_end == (u64)-1) {
|
||||
search_end = key.offset - ext_offset +
|
||||
btrfs_file_extent_ram_bytes(leaf, fi);
|
||||
}
|
||||
|
||||
if (!extent_locked) {
|
||||
lock_start = key.offset;
|
||||
|
@ -4720,7 +4721,7 @@ static noinline int replace_one_extent(struct btrfs_trans_handle *trans,
|
|||
}
|
||||
skip:
|
||||
if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS &&
|
||||
key.offset >= first_pos + extent_key->offset)
|
||||
key.offset >= search_end)
|
||||
break;
|
||||
|
||||
cond_resched();
|
||||
|
|
Loading…
Reference in a new issue