btrfs: fix truncate throttling
authorJosef Bacik <josef@toxicpanda.com>
Mon, 3 Dec 2018 15:20:38 +0000 (10:20 -0500)
committerDavid Sterba <dsterba@suse.com>
Mon, 17 Dec 2018 13:51:47 +0000 (14:51 +0100)
We have a bunch of magic to make sure we're throttling delayed refs when
truncating a file.  Now that we have a delayed refs rsv and a mechanism
for refilling that reserve simply use that instead of all of this magic.

Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/inode.c

index b6c6d8862b80072c12ff24959f0e33c5972844dd..c5c27d5457cc613958d1292a0888fc71a9e31ec3 100644 (file)
@@ -4442,31 +4442,6 @@ out:
        return err;
 }
 
-static int truncate_space_check(struct btrfs_trans_handle *trans,
-                               struct btrfs_root *root,
-                               u64 bytes_deleted)
-{
-       struct btrfs_fs_info *fs_info = root->fs_info;
-       int ret;
-
-       /*
-        * This is only used to apply pressure to the enospc system, we don't
-        * intend to use this reservation at all.
-        */
-       bytes_deleted = btrfs_csum_bytes_to_leaves(fs_info, bytes_deleted);
-       bytes_deleted *= fs_info->nodesize;
-       ret = btrfs_block_rsv_add(root, &fs_info->trans_block_rsv,
-                                 bytes_deleted, BTRFS_RESERVE_NO_FLUSH);
-       if (!ret) {
-               trace_btrfs_space_reservation(fs_info, "transaction",
-                                             trans->transid,
-                                             bytes_deleted, 1);
-               trans->bytes_reserved += bytes_deleted;
-       }
-       return ret;
-
-}
-
 /*
  * Return this if we need to call truncate_block for the last bit of the
  * truncate.
@@ -4511,7 +4486,6 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
        u64 bytes_deleted = 0;
        bool be_nice = false;
        bool should_throttle = false;
-       bool should_end = false;
 
        BUG_ON(new_size > 0 && min_type != BTRFS_EXTENT_DATA_KEY);
 
@@ -4724,15 +4698,7 @@ delete:
                                btrfs_abort_transaction(trans, ret);
                                break;
                        }
-                       if (btrfs_should_throttle_delayed_refs(trans))
-                               btrfs_async_run_delayed_refs(fs_info,
-                                       trans->delayed_ref_updates * 2,
-                                       trans->transid, 0);
                        if (be_nice) {
-                               if (truncate_space_check(trans, root,
-                                                        extent_num_bytes)) {
-                                       should_end = true;
-                               }
                                if (btrfs_should_throttle_delayed_refs(trans))
                                        should_throttle = true;
                        }
@@ -4743,7 +4709,7 @@ delete:
 
                if (path->slots[0] == 0 ||
                    path->slots[0] != pending_del_slot ||
-                   should_throttle || should_end) {
+                   should_throttle) {
                        if (pending_del_nr) {
                                ret = btrfs_del_items(trans, root, path,
                                                pending_del_slot,
@@ -4755,23 +4721,24 @@ delete:
                                pending_del_nr = 0;
                        }
                        btrfs_release_path(path);
-                       if (should_throttle) {
-                               unsigned long updates = trans->delayed_ref_updates;
-                               if (updates) {
-                                       trans->delayed_ref_updates = 0;
-                                       ret = btrfs_run_delayed_refs(trans,
-                                                                  updates * 2);
-                                       if (ret)
-                                               break;
-                               }
-                       }
+
                        /*
-                        * if we failed to refill our space rsv, bail out
-                        * and let the transaction restart
+                        * We can generate a lot of delayed refs, so we need to
+                        * throttle every once and a while and make sure we're
+                        * adding enough space to keep up with the work we are
+                        * generating.  Since we hold a transaction here we
+                        * can't flush, and we don't want to FLUSH_LIMIT because
+                        * we could have generated too many delayed refs to
+                        * actually allocate, so just bail if we're short and
+                        * let the normal reservation dance happen higher up.
                         */
-                       if (should_end) {
-                               ret = -EAGAIN;
-                               break;
+                       if (should_throttle) {
+                               ret = btrfs_delayed_refs_rsv_refill(fs_info,
+                                                       BTRFS_RESERVE_NO_FLUSH);
+                               if (ret) {
+                                       ret = -EAGAIN;
+                                       break;
+                               }
                        }
                        goto search_again;
                } else {
@@ -4797,18 +4764,6 @@ out:
        }
 
        btrfs_free_path(path);
-
-       if (be_nice && bytes_deleted > SZ_32M && (ret >= 0 || ret == -EAGAIN)) {
-               unsigned long updates = trans->delayed_ref_updates;
-               int err;
-
-               if (updates) {
-                       trans->delayed_ref_updates = 0;
-                       err = btrfs_run_delayed_refs(trans, updates * 2);
-                       if (err)
-                               ret = err;
-               }
-       }
        return ret;
 }