summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik2011-01-24 22:43:19 +0100
committerChris Mason2011-01-28 22:40:37 +0100
commite9e22899de661af94cb9995885fd04e4c738838b (patch)
tree3932040f0c5416e6ecbf508fa5d99b50eefbbc18
parentBtrfs: fix check_path_shared so it returns the right value (diff)
downloadkernel-qcow2-linux-e9e22899de661af94cb9995885fd04e4c738838b.tar.gz
kernel-qcow2-linux-e9e22899de661af94cb9995885fd04e4c738838b.tar.xz
kernel-qcow2-linux-e9e22899de661af94cb9995885fd04e4c738838b.zip
Btrfs: do not release more reserved bytes to the global_block_rsv than we need
When we do btrfs_block_rsv_release, if global_block_rsv is not full we will release all the extra bytes to global_block_rsv, even if it's only a little short of the amount of space that we need to reserve. This causes us to starve ourselves of reservable space during the transaction which will force us to shrink delalloc bytes and commit the transaction more often than we should. So instead just add the amount of bytes we need to add to the global reserve so reserved == size, and then add the rest back into the space_info for general use. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/extent-tree.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 98ee139885cc..7af618dcf2c0 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3589,8 +3589,20 @@ void block_rsv_release_bytes(struct btrfs_block_rsv *block_rsv,
if (num_bytes > 0) {
if (dest) {
- block_rsv_add_bytes(dest, num_bytes, 0);
- } else {
+ spin_lock(&dest->lock);
+ if (!dest->full) {
+ u64 bytes_to_add;
+
+ bytes_to_add = dest->size - dest->reserved;
+ bytes_to_add = min(num_bytes, bytes_to_add);
+ dest->reserved += bytes_to_add;
+ if (dest->reserved >= dest->size)
+ dest->full = 1;
+ num_bytes -= bytes_to_add;
+ }
+ spin_unlock(&dest->lock);
+ }
+ if (num_bytes) {
spin_lock(&space_info->lock);
space_info->bytes_reserved -= num_bytes;
spin_unlock(&space_info->lock);