]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
btrfs: add and use a log root field to struct walk_control
authorFilipe Manana <fdmanana@suse.com>
Tue, 26 Aug 2025 16:25:56 +0000 (17:25 +0100)
committerDavid Sterba <dsterba@suse.com>
Tue, 23 Sep 2025 06:49:17 +0000 (08:49 +0200)
Instead of passing an extra log root parameter for the log tree walk
functions and callbacks, add the log tree to struct walk_control and
make those functions and callbacks extract the log root from that
structure, reducing the number of parameters. This also simplifies
further upcoming changes to report log tree replay failures.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/tree-log.c

index 321ec0de07336a133ff66719b3bde39362f78cec..7d1b21df698d9fb2ab852ed5a542f2906b1cac7f 100644 (file)
@@ -336,6 +336,9 @@ struct walk_control {
         */
        struct btrfs_root *root;
 
+       /* The log tree we are currently processing (not NULL for any stage). */
+       struct btrfs_root *log;
+
        /* the trans handle for the current replay */
        struct btrfs_trans_handle *trans;
 
@@ -344,17 +347,17 @@ struct walk_control {
         * passed in, and it must be checked or read if you need the data
         * inside it
         */
-       int (*process_func)(struct btrfs_root *log, struct extent_buffer *eb,
+       int (*process_func)(struct extent_buffer *eb,
                            struct walk_control *wc, u64 gen, int level);
 };
 
 /*
  * process_func used to pin down extents, write them or wait on them
  */
-static int process_one_buffer(struct btrfs_root *log,
-                             struct extent_buffer *eb,
+static int process_one_buffer(struct extent_buffer *eb,
                              struct walk_control *wc, u64 gen, int level)
 {
+       struct btrfs_root *log = wc->log;
        struct btrfs_trans_handle *trans = wc->trans;
        struct btrfs_fs_info *fs_info = log->fs_info;
        int ret = 0;
@@ -2569,7 +2572,7 @@ out:
  * only in the log (references come from either directory items or inode
  * back refs).
  */
-static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
+static int replay_one_buffer(struct extent_buffer *eb,
                             struct walk_control *wc, u64 gen, int level)
 {
        int nritems;
@@ -2579,6 +2582,7 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
        };
        struct btrfs_path *path;
        struct btrfs_root *root = wc->root;
+       struct btrfs_root *log = wc->log;
        struct btrfs_trans_handle *trans = wc->trans;
        struct btrfs_key key;
        int i;
@@ -2779,11 +2783,10 @@ static int clean_log_buffer(struct btrfs_trans_handle *trans,
 }
 
 static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
-                                  struct btrfs_root *log,
                                   struct btrfs_path *path, int *level,
                                   struct walk_control *wc)
 {
-       struct btrfs_fs_info *fs_info = log->fs_info;
+       struct btrfs_fs_info *fs_info = wc->log->fs_info;
        u64 bytenr;
        u64 ptr_gen;
        struct extent_buffer *next;
@@ -2821,7 +2824,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
                }
 
                if (*level == 1) {
-                       ret = wc->process_func(log, next, wc, ptr_gen, *level - 1);
+                       ret = wc->process_func(next, wc, ptr_gen, *level - 1);
                        if (ret) {
                                free_extent_buffer(next);
                                return ret;
@@ -2872,7 +2875,6 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
 }
 
 static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
-                                struct btrfs_root *log,
                                 struct btrfs_path *path, int *level,
                                 struct walk_control *wc)
 {
@@ -2888,7 +2890,7 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
                        WARN_ON(*level == 0);
                        return 0;
                } else {
-                       ret = wc->process_func(log, path->nodes[*level], wc,
+                       ret = wc->process_func(path->nodes[*level], wc,
                                 btrfs_header_generation(path->nodes[*level]),
                                 *level);
                        if (ret)
@@ -2912,9 +2914,9 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
  * the tree freeing any blocks that have a ref count of zero after being
  * decremented.
  */
-static int walk_log_tree(struct btrfs_trans_handle *trans,
-                        struct btrfs_root *log, struct walk_control *wc)
+static int walk_log_tree(struct btrfs_trans_handle *trans, struct walk_control *wc)
 {
+       struct btrfs_root *log = wc->log;
        int ret = 0;
        int wret;
        int level;
@@ -2932,7 +2934,7 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
        path->slots[level] = 0;
 
        while (1) {
-               wret = walk_down_log_tree(trans, log, path, &level, wc);
+               wret = walk_down_log_tree(trans, path, &level, wc);
                if (wret > 0)
                        break;
                if (wret < 0) {
@@ -2940,7 +2942,7 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
                        goto out;
                }
 
-               wret = walk_up_log_tree(trans, log, path, &level, wc);
+               wret = walk_up_log_tree(trans, path, &level, wc);
                if (wret > 0)
                        break;
                if (wret < 0) {
@@ -2951,7 +2953,7 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
 
        /* was the root node processed? if not, catch it here */
        if (path->nodes[orig_level]) {
-               ret = wc->process_func(log, path->nodes[orig_level], wc,
+               ret = wc->process_func(path->nodes[orig_level], wc,
                         btrfs_header_generation(path->nodes[orig_level]),
                         orig_level);
                if (ret)
@@ -3423,11 +3425,12 @@ static void free_log_tree(struct btrfs_trans_handle *trans,
        int ret;
        struct walk_control wc = {
                .free = true,
-               .process_func = process_one_buffer
+               .process_func = process_one_buffer,
+               .log = log,
        };
 
        if (log->node) {
-               ret = walk_log_tree(trans, log, &wc);
+               ret = walk_log_tree(trans, &wc);
                if (ret) {
                        /*
                         * We weren't able to traverse the entire log tree, the
@@ -7441,8 +7444,10 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
 
        wc.trans = trans;
        wc.pin = true;
+       wc.log = log_root_tree;
 
-       ret = walk_log_tree(trans, log_root_tree, &wc);
+       ret = walk_log_tree(trans, &wc);
+       wc.log = NULL;
        if (ret) {
                btrfs_abort_transaction(trans, ret);
                goto error;
@@ -7454,7 +7459,6 @@ again:
        key.offset = (u64)-1;
 
        while (1) {
-               struct btrfs_root *log;
                struct btrfs_key found_key;
 
                ret = btrfs_search_slot(NULL, log_root_tree, &key, path, 0, 0);
@@ -7474,9 +7478,10 @@ again:
                if (found_key.objectid != BTRFS_TREE_LOG_OBJECTID)
                        break;
 
-               log = btrfs_read_tree_root(log_root_tree, &found_key);
-               if (IS_ERR(log)) {
-                       ret = PTR_ERR(log);
+               wc.log = btrfs_read_tree_root(log_root_tree, &found_key);
+               if (IS_ERR(wc.log)) {
+                       ret = PTR_ERR(wc.log);
+                       wc.log = NULL;
                        btrfs_abort_transaction(trans, ret);
                        goto error;
                }
@@ -7486,7 +7491,8 @@ again:
                        ret = PTR_ERR(wc.root);
                        wc.root = NULL;
                        if (ret != -ENOENT) {
-                               btrfs_put_root(log);
+                               btrfs_put_root(wc.log);
+                               wc.log = NULL;
                                btrfs_abort_transaction(trans, ret);
                                goto error;
                        }
@@ -7502,23 +7508,24 @@ again:
                         * block from being modified, and we'll just bail for
                         * each subsequent pass.
                         */
-                       ret = btrfs_pin_extent_for_log_replay(trans, log->node);
+                       ret = btrfs_pin_extent_for_log_replay(trans, wc.log->node);
                        if (ret) {
-                               btrfs_put_root(log);
+                               btrfs_put_root(wc.log);
+                               wc.log = NULL;
                                btrfs_abort_transaction(trans, ret);
                                goto error;
                        }
                        goto next;
                }
 
-               wc.root->log_root = log;
+               wc.root->log_root = wc.log;
                ret = btrfs_record_root_in_trans(trans, wc.root);
                if (ret) {
                        btrfs_abort_transaction(trans, ret);
                        goto next;
                }
 
-               ret = walk_log_tree(trans, log, &wc);
+               ret = walk_log_tree(trans, &wc);
                if (ret) {
                        btrfs_abort_transaction(trans, ret);
                        goto next;
@@ -7551,7 +7558,8 @@ next:
                        wc.root->log_root = NULL;
                        btrfs_put_root(wc.root);
                }
-               btrfs_put_root(log);
+               btrfs_put_root(wc.log);
+               wc.log = NULL;
 
                if (ret)
                        goto error;