diff options
author | Josef Bacik <josef@redhat.com> | 2011-01-21 16:10:01 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2011-01-31 16:27:28 -0500 |
commit | b1953bcec95c189b1eea690a08e89646d7750bda (patch) | |
tree | be7906f6568daecc6196433053ff0ea785b3d175 | |
parent | 7adf5dfbb3af65a00e20b3ead224c3a1b40e4ec4 (diff) |
Btrfs: make shrink_delalloc a little friendlier
Xfstests 224 will just sit there and spin for ever until eventually we give up
flushing delalloc and exit. On my box this took several hours. I could not
interrupt this process either, even though we use INTERRUPTIBLE. So do 2 things
1) Keep us from looping over and over again without reclaiming anything
2) If we get interrupted exit the loop
I tested this and the test now exits in a reasonable amount of time, and can be
interrupted with ctrl+c. 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.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index ff6bbfd75cf7..f96641a93fc9 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3345,8 +3345,10 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans, | |||
3345 | u64 reserved; | 3345 | u64 reserved; |
3346 | u64 max_reclaim; | 3346 | u64 max_reclaim; |
3347 | u64 reclaimed = 0; | 3347 | u64 reclaimed = 0; |
3348 | long time_left; | ||
3348 | int pause = 1; | 3349 | int pause = 1; |
3349 | int nr_pages = (2 * 1024 * 1024) >> PAGE_CACHE_SHIFT; | 3350 | int nr_pages = (2 * 1024 * 1024) >> PAGE_CACHE_SHIFT; |
3351 | int loops = 0; | ||
3350 | 3352 | ||
3351 | block_rsv = &root->fs_info->delalloc_block_rsv; | 3353 | block_rsv = &root->fs_info->delalloc_block_rsv; |
3352 | space_info = block_rsv->space_info; | 3354 | space_info = block_rsv->space_info; |
@@ -3359,7 +3361,7 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans, | |||
3359 | 3361 | ||
3360 | max_reclaim = min(reserved, to_reclaim); | 3362 | max_reclaim = min(reserved, to_reclaim); |
3361 | 3363 | ||
3362 | while (1) { | 3364 | while (loops < 1024) { |
3363 | /* have the flusher threads jump in and do some IO */ | 3365 | /* have the flusher threads jump in and do some IO */ |
3364 | smp_mb(); | 3366 | smp_mb(); |
3365 | nr_pages = min_t(unsigned long, nr_pages, | 3367 | nr_pages = min_t(unsigned long, nr_pages, |
@@ -3367,8 +3369,12 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans, | |||
3367 | writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages); | 3369 | writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages); |
3368 | 3370 | ||
3369 | spin_lock(&space_info->lock); | 3371 | spin_lock(&space_info->lock); |
3370 | if (reserved > space_info->bytes_reserved) | 3372 | if (reserved > space_info->bytes_reserved) { |
3373 | loops = 0; | ||
3371 | reclaimed += reserved - space_info->bytes_reserved; | 3374 | reclaimed += reserved - space_info->bytes_reserved; |
3375 | } else { | ||
3376 | loops++; | ||
3377 | } | ||
3372 | reserved = space_info->bytes_reserved; | 3378 | reserved = space_info->bytes_reserved; |
3373 | spin_unlock(&space_info->lock); | 3379 | spin_unlock(&space_info->lock); |
3374 | 3380 | ||
@@ -3379,7 +3385,12 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans, | |||
3379 | return -EAGAIN; | 3385 | return -EAGAIN; |
3380 | 3386 | ||
3381 | __set_current_state(TASK_INTERRUPTIBLE); | 3387 | __set_current_state(TASK_INTERRUPTIBLE); |
3382 | schedule_timeout(pause); | 3388 | time_left = schedule_timeout(pause); |
3389 | |||
3390 | /* We were interrupted, exit */ | ||
3391 | if (time_left) | ||
3392 | break; | ||
3393 | |||
3383 | pause <<= 1; | 3394 | pause <<= 1; |
3384 | if (pause > HZ / 10) | 3395 | if (pause > HZ / 10) |
3385 | pause = HZ / 10; | 3396 | pause = HZ / 10; |