aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 100e409e9053..f1db57d4a016 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3343,15 +3343,16 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
3343 u64 max_reclaim; 3343 u64 max_reclaim;
3344 u64 reclaimed = 0; 3344 u64 reclaimed = 0;
3345 long time_left; 3345 long time_left;
3346 int pause = 1;
3347 int nr_pages = (2 * 1024 * 1024) >> PAGE_CACHE_SHIFT; 3346 int nr_pages = (2 * 1024 * 1024) >> PAGE_CACHE_SHIFT;
3348 int loops = 0; 3347 int loops = 0;
3348 unsigned long progress;
3349 3349
3350 block_rsv = &root->fs_info->delalloc_block_rsv; 3350 block_rsv = &root->fs_info->delalloc_block_rsv;
3351 space_info = block_rsv->space_info; 3351 space_info = block_rsv->space_info;
3352 3352
3353 smp_mb(); 3353 smp_mb();
3354 reserved = space_info->bytes_reserved; 3354 reserved = space_info->bytes_reserved;
3355 progress = space_info->reservation_progress;
3355 3356
3356 if (reserved == 0) 3357 if (reserved == 0)
3357 return 0; 3358 return 0;
@@ -3366,31 +3367,36 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
3366 writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages); 3367 writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages);
3367 3368
3368 spin_lock(&space_info->lock); 3369 spin_lock(&space_info->lock);
3369 if (reserved > space_info->bytes_reserved) { 3370 if (reserved > space_info->bytes_reserved)
3370 loops = 0;
3371 reclaimed += reserved - space_info->bytes_reserved; 3371 reclaimed += reserved - space_info->bytes_reserved;
3372 } else {
3373 loops++;
3374 }
3375 reserved = space_info->bytes_reserved; 3372 reserved = space_info->bytes_reserved;
3376 spin_unlock(&space_info->lock); 3373 spin_unlock(&space_info->lock);
3377 3374
3375 loops++;
3376
3378 if (reserved == 0 || reclaimed >= max_reclaim) 3377 if (reserved == 0 || reclaimed >= max_reclaim)
3379 break; 3378 break;
3380 3379
3381 if (trans && trans->transaction->blocked) 3380 if (trans && trans->transaction->blocked)
3382 return -EAGAIN; 3381 return -EAGAIN;
3383 3382
3384 __set_current_state(TASK_INTERRUPTIBLE); 3383 time_left = schedule_timeout_interruptible(1);
3385 time_left = schedule_timeout(pause);
3386 3384
3387 /* We were interrupted, exit */ 3385 /* We were interrupted, exit */
3388 if (time_left) 3386 if (time_left)
3389 break; 3387 break;
3390 3388
3391 pause <<= 1; 3389 /* we've kicked the IO a few times, if anything has been freed,
3392 if (pause > HZ / 10) 3390 * exit. There is no sense in looping here for a long time
3393 pause = HZ / 10; 3391 * when we really need to commit the transaction, or there are
3392 * just too many writers without enough free space
3393 */
3394
3395 if (loops > 3) {
3396 smp_mb();
3397 if (progress != space_info->reservation_progress)
3398 break;
3399 }
3394 3400
3395 } 3401 }
3396 return reclaimed >= to_reclaim; 3402 return reclaimed >= to_reclaim;
@@ -3613,6 +3619,7 @@ void block_rsv_release_bytes(struct btrfs_block_rsv *block_rsv,
3613 if (num_bytes) { 3619 if (num_bytes) {
3614 spin_lock(&space_info->lock); 3620 spin_lock(&space_info->lock);
3615 space_info->bytes_reserved -= num_bytes; 3621 space_info->bytes_reserved -= num_bytes;
3622 space_info->reservation_progress++;
3616 spin_unlock(&space_info->lock); 3623 spin_unlock(&space_info->lock);
3617 } 3624 }
3618 } 3625 }
@@ -3845,6 +3852,7 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info)
3845 if (block_rsv->reserved >= block_rsv->size) { 3852 if (block_rsv->reserved >= block_rsv->size) {
3846 num_bytes = block_rsv->reserved - block_rsv->size; 3853 num_bytes = block_rsv->reserved - block_rsv->size;
3847 sinfo->bytes_reserved -= num_bytes; 3854 sinfo->bytes_reserved -= num_bytes;
3855 sinfo->reservation_progress++;
3848 block_rsv->reserved = block_rsv->size; 3856 block_rsv->reserved = block_rsv->size;
3849 block_rsv->full = 1; 3857 block_rsv->full = 1;
3850 } 3858 }
@@ -4006,7 +4014,6 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
4006 to_reserve = 0; 4014 to_reserve = 0;
4007 } 4015 }
4008 spin_unlock(&BTRFS_I(inode)->accounting_lock); 4016 spin_unlock(&BTRFS_I(inode)->accounting_lock);
4009
4010 to_reserve += calc_csum_metadata_size(inode, num_bytes); 4017 to_reserve += calc_csum_metadata_size(inode, num_bytes);
4011 ret = reserve_metadata_bytes(NULL, root, block_rsv, to_reserve, 1); 4018 ret = reserve_metadata_bytes(NULL, root, block_rsv, to_reserve, 1);
4012 if (ret) 4019 if (ret)
@@ -4134,6 +4141,7 @@ static int update_block_group(struct btrfs_trans_handle *trans,
4134 btrfs_set_block_group_used(&cache->item, old_val); 4141 btrfs_set_block_group_used(&cache->item, old_val);
4135 cache->reserved -= num_bytes; 4142 cache->reserved -= num_bytes;
4136 cache->space_info->bytes_reserved -= num_bytes; 4143 cache->space_info->bytes_reserved -= num_bytes;
4144 cache->space_info->reservation_progress++;
4137 cache->space_info->bytes_used += num_bytes; 4145 cache->space_info->bytes_used += num_bytes;
4138 cache->space_info->disk_used += num_bytes * factor; 4146 cache->space_info->disk_used += num_bytes * factor;
4139 spin_unlock(&cache->lock); 4147 spin_unlock(&cache->lock);
@@ -4185,6 +4193,7 @@ static int pin_down_extent(struct btrfs_root *root,
4185 if (reserved) { 4193 if (reserved) {
4186 cache->reserved -= num_bytes; 4194 cache->reserved -= num_bytes;
4187 cache->space_info->bytes_reserved -= num_bytes; 4195 cache->space_info->bytes_reserved -= num_bytes;
4196 cache->space_info->reservation_progress++;
4188 } 4197 }
4189 spin_unlock(&cache->lock); 4198 spin_unlock(&cache->lock);
4190 spin_unlock(&cache->space_info->lock); 4199 spin_unlock(&cache->space_info->lock);
@@ -4235,6 +4244,7 @@ static int update_reserved_bytes(struct btrfs_block_group_cache *cache,
4235 space_info->bytes_readonly += num_bytes; 4244 space_info->bytes_readonly += num_bytes;
4236 cache->reserved -= num_bytes; 4245 cache->reserved -= num_bytes;
4237 space_info->bytes_reserved -= num_bytes; 4246 space_info->bytes_reserved -= num_bytes;
4247 space_info->reservation_progress++;
4238 } 4248 }
4239 spin_unlock(&cache->lock); 4249 spin_unlock(&cache->lock);
4240 spin_unlock(&space_info->lock); 4250 spin_unlock(&space_info->lock);
@@ -4713,6 +4723,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
4713 if (ret) { 4723 if (ret) {
4714 spin_lock(&cache->space_info->lock); 4724 spin_lock(&cache->space_info->lock);
4715 cache->space_info->bytes_reserved -= buf->len; 4725 cache->space_info->bytes_reserved -= buf->len;
4726 cache->space_info->reservation_progress++;
4716 spin_unlock(&cache->space_info->lock); 4727 spin_unlock(&cache->space_info->lock);
4717 } 4728 }
4718 goto out; 4729 goto out;