btrfs: add trans argument to btrfs_clean_tree_block
authorJosef Bacik <josef@toxicpanda.com>
Thu, 26 Jan 2023 21:00:55 +0000 (16:00 -0500)
committerDavid Sterba <dsterba@suse.com>
Wed, 15 Feb 2023 18:38:53 +0000 (19:38 +0100)
We check the header generation in the extent buffer against the current
running transaction id to see if it's safe to clear DIRTY on this
buffer.  Generally speaking if we're clearing the buffer dirty we're
holding the transaction open, but in the case of cleaning up an aborted
transaction we don't, so we have extra checks in that path to check the
transid.  To allow for a future cleanup go ahead and pass in the trans
handle so we don't have to rely on ->running_transaction being set.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/ctree.c
fs/btrfs/disk-io.c
fs/btrfs/disk-io.h
fs/btrfs/extent-tree.c
fs/btrfs/free-space-tree.c
fs/btrfs/ioctl.c
fs/btrfs/qgroup.c
fs/btrfs/tree-log.c

index 4754c9101a4c1bd25c61a964fbba4fec535af446..cae2df92e3b0ecdeb141f75ac79c064eba41e244 100644 (file)
@@ -484,7 +484,7 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
                        if (ret)
                                return ret;
                }
-               btrfs_clean_tree_block(buf);
+               btrfs_clean_tree_block(trans, buf);
                *last_ref = 1;
        }
        return 0;
@@ -1054,7 +1054,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
 
                path->locks[level] = 0;
                path->nodes[level] = NULL;
-               btrfs_clean_tree_block(mid);
+               btrfs_clean_tree_block(trans, mid);
                btrfs_tree_unlock(mid);
                /* once for the path */
                free_extent_buffer(mid);
@@ -1115,7 +1115,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
                if (wret < 0 && wret != -ENOSPC)
                        ret = wret;
                if (btrfs_header_nritems(right) == 0) {
-                       btrfs_clean_tree_block(right);
+                       btrfs_clean_tree_block(trans, right);
                        btrfs_tree_unlock(right);
                        del_ptr(root, path, level + 1, pslot + 1);
                        root_sub_used(root, right->len);
@@ -1161,7 +1161,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
                BUG_ON(wret == 1);
        }
        if (btrfs_header_nritems(mid) == 0) {
-               btrfs_clean_tree_block(mid);
+               btrfs_clean_tree_block(trans, mid);
                btrfs_tree_unlock(mid);
                del_ptr(root, path, level + 1, pslot);
                root_sub_used(root, mid->len);
@@ -3041,7 +3041,8 @@ noinline int btrfs_leaf_free_space(struct extent_buffer *leaf)
  * min slot controls the lowest index we're willing to push to the
  * right.  We'll push up to and including min_slot, but no lower
  */
-static noinline int __push_leaf_right(struct btrfs_path *path,
+static noinline int __push_leaf_right(struct btrfs_trans_handle *trans,
+                                     struct btrfs_path *path,
                                      int data_size, int empty,
                                      struct extent_buffer *right,
                                      int free_space, u32 left_nritems,
@@ -3139,7 +3140,7 @@ static noinline int __push_leaf_right(struct btrfs_path *path,
        if (left_nritems)
                btrfs_mark_buffer_dirty(left);
        else
-               btrfs_clean_tree_block(left);
+               btrfs_clean_tree_block(trans, left);
 
        btrfs_mark_buffer_dirty(right);
 
@@ -3151,7 +3152,7 @@ static noinline int __push_leaf_right(struct btrfs_path *path,
        if (path->slots[0] >= left_nritems) {
                path->slots[0] -= left_nritems;
                if (btrfs_header_nritems(path->nodes[0]) == 0)
-                       btrfs_clean_tree_block(path->nodes[0]);
+                       btrfs_clean_tree_block(trans, path->nodes[0]);
                btrfs_tree_unlock(path->nodes[0]);
                free_extent_buffer(path->nodes[0]);
                path->nodes[0] = right;
@@ -3243,8 +3244,8 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
                return 0;
        }
 
-       return __push_leaf_right(path, min_data_size, empty,
-                               right, free_space, left_nritems, min_slot);
+       return __push_leaf_right(trans, path, min_data_size, empty, right,
+                                free_space, left_nritems, min_slot);
 out_unlock:
        btrfs_tree_unlock(right);
        free_extent_buffer(right);
@@ -3259,7 +3260,8 @@ out_unlock:
  * item at 'max_slot' won't be touched.  Use (u32)-1 to make us do all the
  * items
  */
-static noinline int __push_leaf_left(struct btrfs_path *path, int data_size,
+static noinline int __push_leaf_left(struct btrfs_trans_handle *trans,
+                                    struct btrfs_path *path, int data_size,
                                     int empty, struct extent_buffer *left,
                                     int free_space, u32 right_nritems,
                                     u32 max_slot)
@@ -3363,7 +3365,7 @@ static noinline int __push_leaf_left(struct btrfs_path *path, int data_size,
        if (right_nritems)
                btrfs_mark_buffer_dirty(right);
        else
-               btrfs_clean_tree_block(right);
+               btrfs_clean_tree_block(trans, right);
 
        btrfs_item_key(right, &disk_key, 0);
        fixup_low_keys(path, &disk_key, 1);
@@ -3449,9 +3451,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
                ret = -EUCLEAN;
                goto out;
        }
-       return __push_leaf_left(path, min_data_size,
-                              empty, left, free_space, right_nritems,
-                              max_slot);
+       return __push_leaf_left(trans, path, min_data_size, empty, left,
+                               free_space, right_nritems, max_slot);
 out:
        btrfs_tree_unlock(left);
        free_extent_buffer(left);
@@ -4400,7 +4401,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
                if (leaf == root->node) {
                        btrfs_set_header_level(leaf, 0);
                } else {
-                       btrfs_clean_tree_block(leaf);
+                       btrfs_clean_tree_block(trans, leaf);
                        btrfs_del_leaf(trans, root, path, leaf);
                }
        } else {
index 0da0bde347e54adebd07337648a006df05a18a4c..0b5e63929a47695376cfcbf006f474ccd34aba34 100644 (file)
@@ -868,11 +868,11 @@ struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
 
 }
 
-void btrfs_clean_tree_block(struct extent_buffer *buf)
+void btrfs_clean_tree_block(struct btrfs_trans_handle *trans,
+                           struct extent_buffer *buf)
 {
        struct btrfs_fs_info *fs_info = buf->fs_info;
-       if (btrfs_header_generation(buf) ==
-           fs_info->running_transaction->transid) {
+       if (btrfs_header_generation(buf) == trans->transid) {
                btrfs_assert_tree_write_locked(buf);
 
                if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &buf->bflags)) {
index 3b53fc29a85888616cdd2f32dade0434c1818f0c..d5466f1846879a9dac3f2512f86199041786f838 100644 (file)
@@ -39,7 +39,8 @@ struct extent_buffer *btrfs_find_create_tree_block(
                                                struct btrfs_fs_info *fs_info,
                                                u64 bytenr, u64 owner_root,
                                                int level);
-void btrfs_clean_tree_block(struct extent_buffer *buf);
+void btrfs_clean_tree_block(struct btrfs_trans_handle *trans,
+                           struct extent_buffer *buf);
 void btrfs_clear_oneshot_options(struct btrfs_fs_info *fs_info);
 int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info);
 int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
index 97f2c10ad654025d888eb0bfe6a13f18bbe0ef5c..8465327f31c887cc29caf76220e5864b340ec580 100644 (file)
@@ -4838,7 +4838,7 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
        btrfs_set_buffer_lockdep_class(lockdep_owner, buf, level);
 
        __btrfs_tree_lock(buf, nest);
-       btrfs_clean_tree_block(buf);
+       btrfs_clean_tree_block(trans, buf);
        clear_bit(EXTENT_BUFFER_STALE, &buf->bflags);
        clear_bit(EXTENT_BUFFER_NO_CHECK, &buf->bflags);
 
@@ -5473,7 +5473,7 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
                        btrfs_tree_lock(eb);
                        path->locks[level] = BTRFS_WRITE_LOCK;
                }
-               btrfs_clean_tree_block(eb);
+               btrfs_clean_tree_block(trans, eb);
        }
 
        if (eb == root->node) {
index c667e878ef1a6e93027190bb91f8e2a8054812e4..ab206af5b2f528b1f4ac5aa62c18ef9132f24450 100644 (file)
@@ -1283,7 +1283,7 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info)
        list_del(&free_space_root->dirty_list);
 
        btrfs_tree_lock(free_space_root->node);
-       btrfs_clean_tree_block(free_space_root->node);
+       btrfs_clean_tree_block(trans, free_space_root->node);
        btrfs_tree_unlock(free_space_root->node);
        btrfs_free_tree_block(trans, btrfs_root_id(free_space_root),
                              free_space_root->node, 0, 1);
index 7e348bd2ccdeb39a84ba81ec5e6022e9376aa35e..5fdc09f7f1cb2864347599c8d6762e5302e8a229 100644 (file)
@@ -707,7 +707,7 @@ static noinline int create_subvol(struct user_namespace *mnt_userns,
                 * exists).
                 */
                btrfs_tree_lock(leaf);
-               btrfs_clean_tree_block(leaf);
+               btrfs_clean_tree_block(trans, leaf);
                btrfs_tree_unlock(leaf);
                btrfs_free_tree_block(trans, objectid, leaf, 0, 1);
                free_extent_buffer(leaf);
index af97413abcf43bd7446d79d1e5a5e2a8e9d57872..450d8dd858b29c6beafc752ce05d2a82edd562c3 100644 (file)
@@ -1304,7 +1304,7 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
        list_del(&quota_root->dirty_list);
 
        btrfs_tree_lock(quota_root->node);
-       btrfs_clean_tree_block(quota_root->node);
+       btrfs_clean_tree_block(trans, quota_root->node);
        btrfs_tree_unlock(quota_root->node);
        btrfs_free_tree_block(trans, btrfs_root_id(quota_root),
                              quota_root->node, 0, 1);
index 997ba92481cb9ec05f93c917906fd2bbede2e91c..e683fbb9bb304d608575c63d6b68322a0ab419e3 100644 (file)
@@ -2625,7 +2625,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
 
                                if (trans) {
                                        btrfs_tree_lock(next);
-                                       btrfs_clean_tree_block(next);
+                                       btrfs_clean_tree_block(trans, next);
                                        btrfs_wait_tree_block_writeback(next);
                                        btrfs_tree_unlock(next);
                                        ret = btrfs_pin_reserved_extent(trans,
@@ -2695,7 +2695,7 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
 
                                if (trans) {
                                        btrfs_tree_lock(next);
-                                       btrfs_clean_tree_block(next);
+                                       btrfs_clean_tree_block(trans, next);
                                        btrfs_wait_tree_block_writeback(next);
                                        btrfs_tree_unlock(next);
                                        ret = btrfs_pin_reserved_extent(trans,
@@ -2778,7 +2778,7 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
 
                        if (trans) {
                                btrfs_tree_lock(next);
-                               btrfs_clean_tree_block(next);
+                               btrfs_clean_tree_block(trans, next);
                                btrfs_wait_tree_block_writeback(next);
                                btrfs_tree_unlock(next);
                                ret = btrfs_pin_reserved_extent(trans,