Btrfs: simpler and more efficient cleanup of a log tree's extent io tree
authorFilipe Manana <fdmanana@suse.com>
Fri, 9 Nov 2018 10:43:08 +0000 (10:43 +0000)
committerDavid Sterba <dsterba@suse.com>
Mon, 17 Dec 2018 13:51:31 +0000 (14:51 +0100)
We currently are in a loop finding each range (corresponding to a btree
node/leaf) in a log root's extent io tree and then clean it up. This is a
waste of time since we are traversing the extent io tree's rb_tree more
times then needed (one for a range lookup and another for cleaning it up)
without any good reason.

We free the log trees when we are in the critical section of a transaction
commit (the transaction state is set to TRANS_STATE_COMMIT_DOING), so it's
of great convenience to do everything as fast as possible in order to
reduce the time we block other tasks from starting a new transaction.

So fix this by traversing the extent io tree once and cleaning up all its
records in one go while traversing it.

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

index aa4bc4845ef00236561b1e31319b39b85d4a7681..013d0abcd46bfc8f1ad854f43f5aba867aaf6055 100644 (file)
@@ -3201,8 +3201,6 @@ static void free_log_tree(struct btrfs_trans_handle *trans,
                          struct btrfs_root *log)
 {
        int ret;
-       u64 start;
-       u64 end;
        struct walk_control wc = {
                .free = 1,
                .process_func = process_one_buffer
@@ -3216,18 +3214,8 @@ static void free_log_tree(struct btrfs_trans_handle *trans,
                        btrfs_handle_fs_error(log->fs_info, ret, NULL);
        }
 
-       while (1) {
-               ret = find_first_extent_bit(&log->dirty_log_pages,
-                               0, &start, &end,
-                               EXTENT_DIRTY | EXTENT_NEW | EXTENT_NEED_WAIT,
-                               NULL);
-               if (ret)
-                       break;
-
-               clear_extent_bits(&log->dirty_log_pages, start, end,
-                                 EXTENT_DIRTY | EXTENT_NEW | EXTENT_NEED_WAIT);
-       }
-
+       clear_extent_bits(&log->dirty_log_pages, 0, (u64)-1,
+                         EXTENT_DIRTY | EXTENT_NEW | EXTENT_NEED_WAIT);
        free_extent_buffer(log->node);
        kfree(log);
 }