diff options
Diffstat (limited to 'fs/btrfs/block-group.c')
| -rw-r--r-- | fs/btrfs/block-group.c | 14 | 
1 files changed, 12 insertions, 2 deletions
diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c index 957ad1c31c4f..590b03560265 100644 --- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -2818,10 +2818,20 @@ int btrfs_inc_block_group_ro(struct btrfs_block_group *cache,  	}  	ret = inc_block_group_ro(cache, 0); -	if (!do_chunk_alloc || ret == -ETXTBSY) -		goto unlock_out;  	if (!ret)  		goto out; +	if (ret == -ETXTBSY) +		goto unlock_out; + +	/* +	 * Skip chunk alloction if the bg is SYSTEM, this is to avoid system +	 * chunk allocation storm to exhaust the system chunk array.  Otherwise +	 * we still want to try our best to mark the block group read-only. +	 */ +	if (!do_chunk_alloc && ret == -ENOSPC && +	    (cache->flags & BTRFS_BLOCK_GROUP_SYSTEM)) +		goto unlock_out; +  	alloc_flags = btrfs_get_alloc_profile(fs_info, cache->space_info->flags);  	ret = btrfs_chunk_alloc(trans, alloc_flags, CHUNK_ALLOC_FORCE);  	if (ret < 0)  | 
