aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorLiu Bo <bo.li.liu@oracle.com>2014-09-10 00:58:50 -0400
committerChris Mason <clm@fb.com>2014-09-17 16:38:25 -0400
commit25ce459c1af138f95a3fd318461193397ebb825b (patch)
treec90a31068b55da76f7e99d1d41981c779f918921 /fs/btrfs/extent-tree.c
parentdc046b10c8b7d4f40befe457acb82340bf8b0699 (diff)
Btrfs: fix loop writing of async reclaim
One of my tests shows that when we really don't have space to reclaim via flush_space and also run out of space, this async reclaim work loops on adding itself into the workqueue and keeps writing something to disk according to iostat's results, and these writes mainly comes from commit_transaction which writes super_block. This's unacceptable as it can be bad to disks, especially memeory storages. This adds a check to avoid the above situation. Signed-off-by: Liu Bo <bo.li.liu@oracle.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index e10555823fde..2191a2c7496b 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4343,11 +4343,21 @@ static inline int need_do_async_reclaim(struct btrfs_space_info *space_info,
4343} 4343}
4344 4344
4345static int btrfs_need_do_async_reclaim(struct btrfs_space_info *space_info, 4345static int btrfs_need_do_async_reclaim(struct btrfs_space_info *space_info,
4346 struct btrfs_fs_info *fs_info) 4346 struct btrfs_fs_info *fs_info,
4347 int flush_state)
4347{ 4348{
4348 u64 used; 4349 u64 used;
4349 4350
4350 spin_lock(&space_info->lock); 4351 spin_lock(&space_info->lock);
4352 /*
4353 * We run out of space and have not got any free space via flush_space,
4354 * so don't bother doing async reclaim.
4355 */
4356 if (flush_state > COMMIT_TRANS && space_info->full) {
4357 spin_unlock(&space_info->lock);
4358 return 0;
4359 }
4360
4351 used = space_info->bytes_used + space_info->bytes_reserved + 4361 used = space_info->bytes_used + space_info->bytes_reserved +
4352 space_info->bytes_pinned + space_info->bytes_readonly + 4362 space_info->bytes_pinned + space_info->bytes_readonly +
4353 space_info->bytes_may_use; 4363 space_info->bytes_may_use;
@@ -4380,11 +4390,12 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work)
4380 flush_space(fs_info->fs_root, space_info, to_reclaim, 4390 flush_space(fs_info->fs_root, space_info, to_reclaim,
4381 to_reclaim, flush_state); 4391 to_reclaim, flush_state);
4382 flush_state++; 4392 flush_state++;
4383 if (!btrfs_need_do_async_reclaim(space_info, fs_info)) 4393 if (!btrfs_need_do_async_reclaim(space_info, fs_info,
4394 flush_state))
4384 return; 4395 return;
4385 } while (flush_state <= COMMIT_TRANS); 4396 } while (flush_state <= COMMIT_TRANS);
4386 4397
4387 if (btrfs_need_do_async_reclaim(space_info, fs_info)) 4398 if (btrfs_need_do_async_reclaim(space_info, fs_info, flush_state))
4388 queue_work(system_unbound_wq, work); 4399 queue_work(system_unbound_wq, work);
4389} 4400}
4390 4401