forked from Minki/linux
btrfs: Fix tail space processing in find_free_dev_extent()
It is another reason for NO_SPACE case. When we found enough free space in loop and saved them to max_hole_start/size before, and tail space contains pending extent, origional innocent max_hole_start/size are reset in retry. As a result, find_free_dev_extent() returns less space than it can, and cause NO_SPACE in user program. Reviewed-by: Liu Bo <bo.li.liu@oracle.com> Signed-off-by: Zhao Lei <zhaolei@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
This commit is contained in:
parent
94b947b2f3
commit
f2ab76188e
@ -1134,11 +1134,11 @@ int find_free_dev_extent(struct btrfs_trans_handle *trans,
|
||||
path = btrfs_alloc_path();
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
again:
|
||||
|
||||
max_hole_start = search_start;
|
||||
max_hole_size = 0;
|
||||
hole_size = 0;
|
||||
|
||||
again:
|
||||
if (search_start >= search_end || device->is_tgtdev_for_dev_replace) {
|
||||
ret = -ENOSPC;
|
||||
goto out;
|
||||
@ -1231,21 +1231,23 @@ next:
|
||||
* allocated dev extents, and when shrinking the device,
|
||||
* search_end may be smaller than search_start.
|
||||
*/
|
||||
if (search_end > search_start)
|
||||
if (search_end > search_start) {
|
||||
hole_size = search_end - search_start;
|
||||
|
||||
if (hole_size > max_hole_size) {
|
||||
max_hole_start = search_start;
|
||||
max_hole_size = hole_size;
|
||||
}
|
||||
if (contains_pending_extent(trans, device, &search_start,
|
||||
hole_size)) {
|
||||
btrfs_release_path(path);
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (contains_pending_extent(trans, device, &search_start, hole_size)) {
|
||||
btrfs_release_path(path);
|
||||
goto again;
|
||||
if (hole_size > max_hole_size) {
|
||||
max_hole_start = search_start;
|
||||
max_hole_size = hole_size;
|
||||
}
|
||||
}
|
||||
|
||||
/* See above. */
|
||||
if (hole_size < num_bytes)
|
||||
if (max_hole_size < num_bytes)
|
||||
ret = -ENOSPC;
|
||||
else
|
||||
ret = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user