aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-10-18 13:07:31 -0400
committerJosef Bacik <josef@redhat.com>2011-10-19 15:13:00 -0400
commit7e355b83efa80e5f5821591c13c17649594d82ac (patch)
tree978b21df0e2a77a16fe8383be28a82378a7d662d /fs/btrfs/extent-tree.c
parent36ba022ac0b748dd543f43430b03198e899426c9 (diff)
Btrfs: if we have a lot of pinned space, commit the transaction
Mitch kept hitting a panic because he was getting ENOSPC. One of my previous patches makes it so we are much better at not allocating new metadata chunks. Unfortunately coupled with the overcommit patch this works us into a bit of a problem if we are removing a bunch of space and end up chewing up all of our space with pinned extents. We can allocate chunks fine and overflow is ok, but the only way to reclaim this space is to commit the transaction. So if we go to overcommit, first check and see how much pinned space we have. If we have more than 80% of the free space chewed up with pinned extents, just commit the transaction, this will free up enough space for our reservation and we won't have this problem anymore. With this patch Mitch's test doesn't blow up anymore. Thanks, Reported-and-tested-by: Mitch Harder <mitch.harder@sabayonlinux.org> Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index a5f1421eeee9..4eb7d2ba38f8 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3510,6 +3510,20 @@ again:
3510 u64 profile = btrfs_get_alloc_profile(root, 0); 3510 u64 profile = btrfs_get_alloc_profile(root, 0);
3511 u64 avail; 3511 u64 avail;
3512 3512
3513 /*
3514 * If we have a lot of space that's pinned, don't bother doing
3515 * the overcommit dance yet and just commit the transaction.
3516 */
3517 avail = (space_info->total_bytes - space_info->bytes_used) * 8;
3518 do_div(avail, 10);
3519 if (space_info->bytes_pinned >= avail && flush && !trans &&
3520 !committed) {
3521 space_info->flush = 1;
3522 flushing = true;
3523 spin_unlock(&space_info->lock);
3524 goto commit;
3525 }
3526
3513 spin_lock(&root->fs_info->free_chunk_lock); 3527 spin_lock(&root->fs_info->free_chunk_lock);
3514 avail = root->fs_info->free_chunk_space; 3528 avail = root->fs_info->free_chunk_space;
3515 3529
@@ -3581,6 +3595,7 @@ again:
3581 if (trans) 3595 if (trans)
3582 goto out; 3596 goto out;
3583 3597
3598commit:
3584 ret = -ENOSPC; 3599 ret = -ENOSPC;
3585 if (committed) 3600 if (committed)
3586 goto out; 3601 goto out;