diff options
Diffstat (limited to 'fs/btrfs/relocation.c')
| -rw-r--r-- | fs/btrfs/relocation.c | 13 | 
1 files changed, 12 insertions, 1 deletions
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 0825e4ed9447..31ade5802ae8 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -3654,6 +3654,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)  	u32 item_size;  	int ret;  	int err = 0; +	int progress = 0;  	path = btrfs_alloc_path();  	if (!path) @@ -3666,9 +3667,10 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)  	}  	while (1) { +		progress++;  		trans = btrfs_start_transaction(rc->extent_root, 0);  		BUG_ON(IS_ERR(trans)); - +restart:  		if (update_backref_cache(trans, &rc->backref_cache)) {  			btrfs_end_transaction(trans, rc->extent_root);  			continue; @@ -3781,6 +3783,15 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)  			}  		}  	} +	if (trans && progress && err == -ENOSPC) { +		ret = btrfs_force_chunk_alloc(trans, rc->extent_root, +					      rc->block_group->flags); +		if (ret == 0) { +			err = 0; +			progress = 0; +			goto restart; +		} +	}  	btrfs_release_path(rc->extent_root, path);  	clear_extent_bits(&rc->processed_blocks, 0, (u64)-1, EXTENT_DIRTY,  | 
