diff options
author | Josef Bacik <jbacik@fb.com> | 2015-02-03 07:50:16 -0800 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2015-04-10 14:04:47 -0700 |
commit | 1262133b8d6f10f5ca7621cd4cf65ddf6254126a (patch) | |
tree | ac508ea4fc6d1e9b394ac2bdfee04eb20f5fc930 /fs/btrfs/inode.c | |
parent | 28ed1345a50491d78e1454ad4005dc5d3557a69e (diff) | |
download | linux-1262133b8d6f10f5ca7621cd4cf65ddf6254126a.tar.bz2 |
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.c | 25 |
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, int extent_type = -1; int ret; int err = 0; - int be_nice = 0; u64 ino = btrfs_ino(inode); u64 bytes_deleted = 0; + bool be_nice = 0; + bool should_throttle = 0; BUG_ON(new_size > 0 && min_type != BTRFS_EXTENT_DATA_KEY); @@ -4405,19 +4406,20 @@ delete: btrfs_header_owner(leaf), ino, extent_offset, 0); BUG_ON(ret); - if (be_nice && pending_del_nr && - (pending_del_nr % 16 == 0) && - bytes_deleted > 1024 * 1024) { + if (btrfs_should_throttle_delayed_refs(trans, root)) btrfs_async_run_delayed_refs(root, trans->delayed_ref_updates * 2, 0); - } } if (found_type == BTRFS_INODE_ITEM_KEY) break; + should_throttle = + btrfs_should_throttle_delayed_refs(trans, root); + if (path->slots[0] == 0 || - path->slots[0] != pending_del_slot) { + path->slots[0] != pending_del_slot || + (be_nice && should_throttle)) { if (pending_del_nr) { ret = btrfs_del_items(trans, root, path, pending_del_slot, @@ -4430,6 +4432,15 @@ delete: pending_del_nr = 0; } btrfs_release_path(path); + if (be_nice && should_throttle) { + unsigned long updates = trans->delayed_ref_updates; + if (updates) { + trans->delayed_ref_updates = 0; + ret = btrfs_run_delayed_refs(trans, root, updates * 2); + if (ret && !err) + err = ret; + } + } goto search_again; } else { path->slots[0]--; @@ -4449,7 +4460,7 @@ error: btrfs_free_path(path); - if (be_nice && bytes_deleted > 32 * 1024 * 1024) { + if (be_nice && btrfs_should_throttle_delayed_refs(trans, root)) { unsigned long updates = trans->delayed_ref_updates; if (updates) { trans->delayed_ref_updates = 0; |