btrfs: reloc: move error handling of build_backref_tree() to backref.c
authorQu Wenruo <wqu@suse.com>
Mon, 23 Mar 2020 08:57:15 +0000 (16:57 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 25 May 2020 09:25:21 +0000 (11:25 +0200)
The error cleanup will be extracted as a new function,
btrfs_backref_error_cleanup(), and moved to backref.c and exported for
later usage.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/backref.c
fs/btrfs/backref.h
fs/btrfs/relocation.c

index 3b355be95171a10e26d076aa0184b670e8863196..b38a680e6678b8ca3c32e5d9577e34570f399beb 100644 (file)
@@ -3063,3 +3063,57 @@ int btrfs_backref_finish_upper_links(struct btrfs_backref_cache *cache,
        }
        return 0;
 }
+
+void btrfs_backref_error_cleanup(struct btrfs_backref_cache *cache,
+                                struct btrfs_backref_node *node)
+{
+       struct btrfs_backref_node *lower;
+       struct btrfs_backref_node *upper;
+       struct btrfs_backref_edge *edge;
+
+       while (!list_empty(&cache->useless_node)) {
+               lower = list_first_entry(&cache->useless_node,
+                                  struct btrfs_backref_node, list);
+               list_del_init(&lower->list);
+       }
+       while (!list_empty(&cache->pending_edge)) {
+               edge = list_first_entry(&cache->pending_edge,
+                               struct btrfs_backref_edge, list[UPPER]);
+               list_del(&edge->list[UPPER]);
+               list_del(&edge->list[LOWER]);
+               lower = edge->node[LOWER];
+               upper = edge->node[UPPER];
+               btrfs_backref_free_edge(cache, edge);
+
+               /*
+                * Lower is no longer linked to any upper backref nodes and
+                * isn't in the cache, we can free it ourselves.
+                */
+               if (list_empty(&lower->upper) &&
+                   RB_EMPTY_NODE(&lower->rb_node))
+                       list_add(&lower->list, &cache->useless_node);
+
+               if (!RB_EMPTY_NODE(&upper->rb_node))
+                       continue;
+
+               /* Add this guy's upper edges to the list to process */
+               list_for_each_entry(edge, &upper->upper, list[LOWER])
+                       list_add_tail(&edge->list[UPPER],
+                                     &cache->pending_edge);
+               if (list_empty(&upper->upper))
+                       list_add(&upper->list, &cache->useless_node);
+       }
+
+       while (!list_empty(&cache->useless_node)) {
+               lower = list_first_entry(&cache->useless_node,
+                                  struct btrfs_backref_node, list);
+               list_del_init(&lower->list);
+               if (lower == node)
+                       node = NULL;
+               btrfs_backref_free_node(cache, lower);
+       }
+
+       btrfs_backref_cleanup_node(cache, node);
+       ASSERT(list_empty(&cache->useless_node) &&
+              list_empty(&cache->pending_edge));
+}
index 80a43359d216b870581c3faba958641331385eba..18393cc05ca22ba5a11f5367e7f363e4f3f217f7 100644 (file)
@@ -372,4 +372,7 @@ int btrfs_backref_add_tree_node(struct btrfs_backref_cache *cache,
 int btrfs_backref_finish_upper_links(struct btrfs_backref_cache *cache,
                                     struct btrfs_backref_node *start);
 
+void btrfs_backref_error_cleanup(struct btrfs_backref_cache *cache,
+                                struct btrfs_backref_node *node);
+
 #endif
index a3e63b937290adb36980cf6a5a355f148eec4fc0..80b58358f6883943ef25bd9a76ba2888754ca7ba 100644 (file)
@@ -474,8 +474,6 @@ static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
        /* For searching parent of TREE_BLOCK_REF */
        struct btrfs_path *path;
        struct btrfs_backref_node *cur;
-       struct btrfs_backref_node *upper;
-       struct btrfs_backref_node *lower;
        struct btrfs_backref_node *node = NULL;
        struct btrfs_backref_edge *edge;
        int ret;
@@ -532,51 +530,7 @@ out:
        btrfs_backref_iter_free(iter);
        btrfs_free_path(path);
        if (err) {
-               while (!list_empty(&cache->useless_node)) {
-                       lower = list_first_entry(&cache->useless_node,
-                                          struct btrfs_backref_node, list);
-                       list_del_init(&lower->list);
-               }
-               while (!list_empty(&cache->pending_edge)) {
-                       edge = list_first_entry(&cache->pending_edge,
-                                       struct btrfs_backref_edge, list[UPPER]);
-                       list_del(&edge->list[UPPER]);
-                       list_del(&edge->list[LOWER]);
-                       lower = edge->node[LOWER];
-                       upper = edge->node[UPPER];
-                       btrfs_backref_free_edge(cache, edge);
-
-                       /*
-                        * Lower is no longer linked to any upper backref nodes
-                        * and isn't in the cache, we can free it ourselves.
-                        */
-                       if (list_empty(&lower->upper) &&
-                           RB_EMPTY_NODE(&lower->rb_node))
-                               list_add(&lower->list, &cache->useless_node);
-
-                       if (!RB_EMPTY_NODE(&upper->rb_node))
-                               continue;
-
-                       /* Add this guy's upper edges to the list to process */
-                       list_for_each_entry(edge, &upper->upper, list[LOWER])
-                               list_add_tail(&edge->list[UPPER],
-                                             &cache->pending_edge);
-                       if (list_empty(&upper->upper))
-                               list_add(&upper->list, &cache->useless_node);
-               }
-
-               while (!list_empty(&cache->useless_node)) {
-                       lower = list_first_entry(&cache->useless_node,
-                                          struct btrfs_backref_node, list);
-                       list_del_init(&lower->list);
-                       if (lower == node)
-                               node = NULL;
-                       btrfs_backref_free_node(cache, lower);
-               }
-
-               btrfs_backref_cleanup_node(cache, node);
-               ASSERT(list_empty(&cache->useless_node) &&
-                      list_empty(&cache->pending_edge));
+               btrfs_backref_error_cleanup(cache, node);
                return ERR_PTR(err);
        }
        ASSERT(!node || !node->detached);