Skip to content

Commit 0096420

Browse files
josefbacikkdave
authored andcommitted
btrfs: do not account global reserve in can_overcommit
We ran into a problem in production where a box with plenty of space was getting wedged doing ENOSPC flushing. These boxes only had 20% of the disk allocated, but their metadata space + global reserve was right at the size of their metadata chunk. In this case can_overcommit should be allowing allocations without problem, but there's logic in can_overcommit that doesn't allow us to overcommit if there's not enough real space to satisfy the global reserve. This is for historical reasons. Before there were only certain places we could allocate chunks. We could go to commit the transaction and not have enough space for our pending delayed refs and such and be unable to allocate a new chunk. This would result in a abort because of ENOSPC. This code was added to solve this problem. However since then we've gained the ability to always be able to allocate a chunk. So we can easily overcommit in these cases without risking a transaction abort because of ENOSPC. Also prior to now the global reserve really would be used because that's the space we relied on for delayed refs. With delayed refs being tracked separately we no longer have to worry about running out of delayed refs space while committing. We are much less likely to exhaust our global reserve space during transaction commit. Fix the can_overcommit code to simply see if our current usage + what we want is less than our current free space plus whatever slack space we have in the disk is. This solves the problem we were seeing in production and keeps us from flushing as aggressively as we approach our actual metadata size usage. Reviewed-by: Nikolay Borisov <[email protected]> Signed-off-by: Josef Bacik <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 426551f commit 0096420

File tree

1 file changed

+1
-18
lines changed

1 file changed

+1
-18
lines changed

fs/btrfs/space-info.c

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,7 @@ static int can_overcommit(struct btrfs_fs_info *fs_info,
165165
enum btrfs_reserve_flush_enum flush,
166166
bool system_chunk)
167167
{
168-
struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv;
169168
u64 profile;
170-
u64 space_size;
171169
u64 avail;
172170
u64 used;
173171
int factor;
@@ -181,22 +179,7 @@ static int can_overcommit(struct btrfs_fs_info *fs_info,
181179
else
182180
profile = btrfs_metadata_alloc_profile(fs_info);
183181

184-
used = btrfs_space_info_used(space_info, false);
185-
186-
/*
187-
* We only want to allow over committing if we have lots of actual space
188-
* free, but if we don't have enough space to handle the global reserve
189-
* space then we could end up having a real enospc problem when trying
190-
* to allocate a chunk or some other such important allocation.
191-
*/
192-
spin_lock(&global_rsv->lock);
193-
space_size = calc_global_rsv_need_space(global_rsv);
194-
spin_unlock(&global_rsv->lock);
195-
if (used + space_size >= space_info->total_bytes)
196-
return 0;
197-
198-
used += space_info->bytes_may_use;
199-
182+
used = btrfs_space_info_used(space_info, true);
200183
avail = atomic64_read(&fs_info->free_chunk_space);
201184

202185
/*

0 commit comments

Comments
 (0)