aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fb.com>2015-02-03 10:50:16 -0500
committerChris Mason <clm@fb.com>2015-04-10 17:04:47 -0400
commit1262133b8d6f10f5ca7621cd4cf65ddf6254126a (patch)
treeac508ea4fc6d1e9b394ac2bdfee04eb20f5fc930 /fs/btrfs/inode.c
parent28ed1345a50491d78e1454ad4005dc5d3557a69e (diff)
Btrfs: account for crcs in delayed ref processing
As we delete large extents, we end up doing huge amounts of COW in order to delete the corresponding crcs. This adds accounting so that we keep track of that space and flushing of delayed refs so that we don't build up too much delayed crc work. This helps limit the delayed work that must be done at commit time and tries to avoid ENOSPC aborts because the crcs eat all the global reserves. Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index e3fe137fb826..cec23cf812ee 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -4197,9 +4197,10 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
4197 int extent_type = -1; 4197 int extent_type = -1;
4198 int ret; 4198 int ret;
4199 int err = 0; 4199 int err = 0;
4200 int be_nice = 0;
4201 u64 ino = btrfs_ino(inode); 4200 u64 ino = btrfs_ino(inode);
4202 u64 bytes_deleted = 0; 4201 u64 bytes_deleted = 0;
4202 bool be_nice = 0;
4203 bool should_throttle = 0;
4203 4204
4204 BUG_ON(new_size > 0 && min_type != BTRFS_EXTENT_DATA_KEY); 4205 BUG_ON(new_size > 0 && min_type != BTRFS_EXTENT_DATA_KEY);
4205 4206
@@ -4405,19 +4406,20 @@ delete:
4405 btrfs_header_owner(leaf), 4406 btrfs_header_owner(leaf),
4406 ino, extent_offset, 0); 4407 ino, extent_offset, 0);
4407 BUG_ON(ret); 4408 BUG_ON(ret);
4408 if (be_nice && pending_del_nr && 4409 if (btrfs_should_throttle_delayed_refs(trans, root))
4409 (pending_del_nr % 16 == 0) &&
4410 bytes_deleted > 1024 * 1024) {
4411 btrfs_async_run_delayed_refs(root, 4410 btrfs_async_run_delayed_refs(root,
4412 trans->delayed_ref_updates * 2, 0); 4411 trans->delayed_ref_updates * 2, 0);
4413 }
4414 } 4412 }
4415 4413
4416 if (found_type == BTRFS_INODE_ITEM_KEY) 4414 if (found_type == BTRFS_INODE_ITEM_KEY)
4417 break; 4415 break;
4418 4416
4417 should_throttle =
4418 btrfs_should_throttle_delayed_refs(trans, root);
4419
4419 if (path->slots[0] == 0 || 4420 if (path->slots[0] == 0 ||
4420 path->slots[0] != pending_del_slot) { 4421 path->slots[0] != pending_del_slot ||
4422 (be_nice && should_throttle)) {
4421 if (pending_del_nr) { 4423 if (pending_del_nr) {
4422 ret = btrfs_del_items(trans, root, path, 4424 ret = btrfs_del_items(trans, root, path,
4423 pending_del_slot, 4425 pending_del_slot,
@@ -4430,6 +4432,15 @@ delete:
4430 pending_del_nr = 0; 4432 pending_del_nr = 0;
4431 } 4433 }
4432 btrfs_release_path(path); 4434 btrfs_release_path(path);
4435 if (be_nice && should_throttle) {
4436 unsigned long updates = trans->delayed_ref_updates;
4437 if (updates) {
4438 trans->delayed_ref_updates = 0;
4439 ret = btrfs_run_delayed_refs(trans, root, updates * 2);
4440 if (ret && !err)
4441 err = ret;
4442 }
4443 }
4433 goto search_again; 4444 goto search_again;
4434 } else { 4445 } else {
4435 path->slots[0]--; 4446 path->slots[0]--;
@@ -4449,7 +4460,7 @@ error:
4449 4460
4450 btrfs_free_path(path); 4461 btrfs_free_path(path);
4451 4462
4452 if (be_nice && bytes_deleted > 32 * 1024 * 1024) { 4463 if (be_nice && btrfs_should_throttle_delayed_refs(trans, root)) {
4453 unsigned long updates = trans->delayed_ref_updates; 4464 unsigned long updates = trans->delayed_ref_updates;
4454 if (updates) { 4465 if (updates) {
4455 trans->delayed_ref_updates = 0; 4466 trans->delayed_ref_updates = 0;