diff --git a/[refs] b/[refs] index bb13febe7225..a26cf2454841 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 36ba022ac0b748dd543f43430b03198e899426c9 +refs/heads/master: 7e355b83efa80e5f5821591c13c17649594d82ac diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index a5f1421eeee9..4eb7d2ba38f8 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -3510,6 +3510,20 @@ static int reserve_metadata_bytes(struct btrfs_root *root, u64 profile = btrfs_get_alloc_profile(root, 0); u64 avail; + /* + * If we have a lot of space that's pinned, don't bother doing + * the overcommit dance yet and just commit the transaction. + */ + avail = (space_info->total_bytes - space_info->bytes_used) * 8; + do_div(avail, 10); + if (space_info->bytes_pinned >= avail && flush && !trans && + !committed) { + space_info->flush = 1; + flushing = true; + spin_unlock(&space_info->lock); + goto commit; + } + spin_lock(&root->fs_info->free_chunk_lock); avail = root->fs_info->free_chunk_space; @@ -3581,6 +3595,7 @@ static int reserve_metadata_bytes(struct btrfs_root *root, if (trans) goto out; +commit: ret = -ENOSPC; if (committed) goto out;