btrfs-progs: add btrfs_clear_free_space_tree() from the kernel
[platform/upstream/btrfs-progs.git] / cmds-check.c
index 21b15c8..e28ad2f 100644 (file)
@@ -6670,7 +6670,6 @@ static int record_extent(struct btrfs_trans_handle *trans,
        struct extent_buffer *leaf;
        struct btrfs_key ins_key;
        struct btrfs_extent_item *ei;
-       struct tree_backref *tback;
        struct data_backref *dback;
        struct btrfs_tree_block_info *bi;
 
@@ -6706,7 +6705,6 @@ static int record_extent(struct btrfs_trans_handle *trans,
                } else {
                        struct btrfs_disk_key copy_key;;
 
-                       tback = to_tree_backref(back);
                        bi = (struct btrfs_tree_block_info *)(ei + 1);
                        memset_extent_buffer(leaf, 0, (unsigned long)bi,
                                             sizeof(*bi));
@@ -6772,6 +6770,7 @@ static int record_extent(struct btrfs_trans_handle *trans,
                                dback->found_ref);
        } else {
                u64 parent;
+               struct tree_backref *tback;
 
                tback = to_tree_backref(back);
                if (back->full_backref)
@@ -6809,11 +6808,6 @@ static struct extent_entry *find_most_right_entry(struct list_head *entries)
        struct extent_entry *entry, *best = NULL, *prev = NULL;
 
        list_for_each_entry(entry, entries, list) {
-               if (!prev) {
-                       prev = entry;
-                       continue;
-               }
-
                /*
                 * If there are as many broken entries as entries then we know
                 * not to trust this particular entry.
@@ -6822,6 +6816,16 @@ static struct extent_entry *find_most_right_entry(struct list_head *entries)
                        continue;
 
                /*
+                * Special case, when there are only two entries and 'best' is
+                * the first one
+                */
+               if (!prev) {
+                       best = entry;
+                       prev = entry;
+                       continue;
+               }
+
+               /*
                 * If our current entry == best then we can't be sure our best
                 * is really the best, so we need to keep searching.
                 */
@@ -10586,7 +10590,7 @@ static int fill_csum_tree_from_one_fs_root(struct btrfs_trans_handle *trans,
                                      struct btrfs_root *csum_root,
                                      struct btrfs_root *cur_root)
 {
-       struct btrfs_path *path;
+       struct btrfs_path path;
        struct btrfs_key key;
        struct extent_buffer *node;
        struct btrfs_file_extent_item *fi;
@@ -10596,30 +10600,25 @@ static int fill_csum_tree_from_one_fs_root(struct btrfs_trans_handle *trans,
        int slot = 0;
        int ret = 0;
 
-       path = btrfs_alloc_path();
-       if (!path)
-               return -ENOMEM;
        buf = malloc(cur_root->fs_info->csum_root->sectorsize);
-       if (!buf) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!buf)
+               return -ENOMEM;
 
+       btrfs_init_path(&path);
        key.objectid = 0;
        key.offset = 0;
        key.type = 0;
-
-       ret = btrfs_search_slot(NULL, cur_root, &key, path, 0, 0);
+       ret = btrfs_search_slot(NULL, cur_root, &key, &path, 0, 0);
        if (ret < 0)
                goto out;
        /* Iterate all regular file extents and fill its csum */
        while (1) {
-               btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
+               btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
 
                if (key.type != BTRFS_EXTENT_DATA_KEY)
                        goto next;
-               node = path->nodes[0];
-               slot = path->slots[0];
+               node = path.nodes[0];
+               slot = path.slots[0];
                fi = btrfs_item_ptr(node, slot, struct btrfs_file_extent_item);
                if (btrfs_file_extent_type(node, fi) != BTRFS_FILE_EXTENT_REG)
                        goto next;
@@ -10636,7 +10635,7 @@ next:
                 * TODO: if next leaf is corrupted, jump to nearest next valid
                 * leaf.
                 */
-               ret = btrfs_next_item(cur_root, path);
+               ret = btrfs_next_item(cur_root, &path);
                if (ret < 0)
                        goto out;
                if (ret > 0) {
@@ -10646,7 +10645,7 @@ next:
        }
 
 out:
-       btrfs_free_path(path);
+       btrfs_release_path(&path);
        free(buf);
        return ret;
 }
@@ -10655,7 +10654,7 @@ static int fill_csum_tree_from_fs(struct btrfs_trans_handle *trans,
                                  struct btrfs_root *csum_root)
 {
        struct btrfs_fs_info *fs_info = csum_root->fs_info;
-       struct btrfs_path *path;
+       struct btrfs_path path;
        struct btrfs_root *tree_root = fs_info->tree_root;
        struct btrfs_root *cur_root;
        struct extent_buffer *node;
@@ -10663,15 +10662,11 @@ static int fill_csum_tree_from_fs(struct btrfs_trans_handle *trans,
        int slot = 0;
        int ret = 0;
 
-       path = btrfs_alloc_path();
-       if (!path)
-               return -ENOMEM;
-
+       btrfs_init_path(&path);
        key.objectid = BTRFS_FS_TREE_OBJECTID;
        key.offset = 0;
        key.type = BTRFS_ROOT_ITEM_KEY;
-
-       ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0);
+       ret = btrfs_search_slot(NULL, tree_root, &key, &path, 0, 0);
        if (ret < 0)
                goto out;
        if (ret > 0) {
@@ -10680,8 +10675,8 @@ static int fill_csum_tree_from_fs(struct btrfs_trans_handle *trans,
        }
 
        while (1) {
-               node = path->nodes[0];
-               slot = path->slots[0];
+               node = path.nodes[0];
+               slot = path.slots[0];
                btrfs_item_key_to_cpu(node, &key, slot);
                if (key.objectid > BTRFS_LAST_FREE_OBJECTID)
                        goto out;
@@ -10702,7 +10697,7 @@ static int fill_csum_tree_from_fs(struct btrfs_trans_handle *trans,
                if (ret < 0)
                        goto out;
 next:
-               ret = btrfs_next_item(tree_root, path);
+               ret = btrfs_next_item(tree_root, &path);
                if (ret > 0) {
                        ret = 0;
                        goto out;
@@ -10712,7 +10707,7 @@ next:
        }
 
 out:
-       btrfs_free_path(path);
+       btrfs_release_path(&path);
        return ret;
 }
 
@@ -10720,36 +10715,32 @@ static int fill_csum_tree_from_extent(struct btrfs_trans_handle *trans,
                                      struct btrfs_root *csum_root)
 {
        struct btrfs_root *extent_root = csum_root->fs_info->extent_root;
-       struct btrfs_path *path;
+       struct btrfs_path path;
        struct btrfs_extent_item *ei;
        struct extent_buffer *leaf;
        char *buf;
        struct btrfs_key key;
        int ret;
 
-       path = btrfs_alloc_path();
-       if (!path)
-               return -ENOMEM;
-
+       btrfs_init_path(&path);
        key.objectid = 0;
        key.type = BTRFS_EXTENT_ITEM_KEY;
        key.offset = 0;
-
-       ret = btrfs_search_slot(NULL, extent_root, &key, path, 0, 0);
+       ret = btrfs_search_slot(NULL, extent_root, &key, &path, 0, 0);
        if (ret < 0) {
-               btrfs_free_path(path);
+               btrfs_release_path(&path);
                return ret;
        }
 
        buf = malloc(csum_root->sectorsize);
        if (!buf) {
-               btrfs_free_path(path);
+               btrfs_release_path(&path);
                return -ENOMEM;
        }
 
        while (1) {
-               if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
-                       ret = btrfs_next_leaf(extent_root, path);
+               if (path.slots[0] >= btrfs_header_nritems(path.nodes[0])) {
+                       ret = btrfs_next_leaf(extent_root, &path);
                        if (ret < 0)
                                break;
                        if (ret) {
@@ -10757,19 +10748,19 @@ static int fill_csum_tree_from_extent(struct btrfs_trans_handle *trans,
                                break;
                        }
                }
-               leaf = path->nodes[0];
+               leaf = path.nodes[0];
 
-               btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
+               btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
                if (key.type != BTRFS_EXTENT_ITEM_KEY) {
-                       path->slots[0]++;
+                       path.slots[0]++;
                        continue;
                }
 
-               ei = btrfs_item_ptr(leaf, path->slots[0],
+               ei = btrfs_item_ptr(leaf, path.slots[0],
                                    struct btrfs_extent_item);
                if (!(btrfs_extent_flags(leaf, ei) &
                      BTRFS_EXTENT_FLAG_DATA)) {
-                       path->slots[0]++;
+                       path.slots[0]++;
                        continue;
                }
 
@@ -10777,10 +10768,10 @@ static int fill_csum_tree_from_extent(struct btrfs_trans_handle *trans,
                                    key.offset);
                if (ret)
                        break;
-               path->slots[0]++;
+               path.slots[0]++;
        }
 
-       btrfs_free_path(path);
+       btrfs_release_path(&path);
        free(buf);
        return ret;
 }
@@ -10828,7 +10819,7 @@ static int build_roots_info_cache(struct btrfs_fs_info *info)
        int ret = 0;
        struct btrfs_key key;
        struct extent_buffer *leaf;
-       struct btrfs_path *path;
+       struct btrfs_path path;
 
        if (!roots_info_cache) {
                roots_info_cache = malloc(sizeof(*roots_info_cache));
@@ -10837,24 +10828,20 @@ static int build_roots_info_cache(struct btrfs_fs_info *info)
                cache_tree_init(roots_info_cache);
        }
 
-       path = btrfs_alloc_path();
-       if (!path)
-               return -ENOMEM;
-
+       btrfs_init_path(&path);
        key.objectid = 0;
        key.type = BTRFS_EXTENT_ITEM_KEY;
        key.offset = 0;
-
-       ret = btrfs_search_slot(NULL, info->extent_root, &key, path, 0, 0);
+       ret = btrfs_search_slot(NULL, info->extent_root, &key, &path, 0, 0);
        if (ret < 0)
                goto out;
-       leaf = path->nodes[0];
+       leaf = path.nodes[0];
 
        while (1) {
                struct btrfs_key found_key;
                struct btrfs_extent_item *ei;
                struct btrfs_extent_inline_ref *iref;
-               int slot = path->slots[0];
+               int slot = path.slots[0];
                int type;
                u64 flags;
                u64 root_id;
@@ -10863,18 +10850,18 @@ static int build_roots_info_cache(struct btrfs_fs_info *info)
                struct root_item_info *rii;
 
                if (slot >= btrfs_header_nritems(leaf)) {
-                       ret = btrfs_next_leaf(info->extent_root, path);
+                       ret = btrfs_next_leaf(info->extent_root, &path);
                        if (ret < 0) {
                                break;
                        } else if (ret) {
                                ret = 0;
                                break;
                        }
-                       leaf = path->nodes[0];
-                       slot = path->slots[0];
+                       leaf = path.nodes[0];
+                       slot = path.slots[0];
                }
 
-               btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
+               btrfs_item_key_to_cpu(leaf, &found_key, path.slots[0]);
 
                if (found_key.type != BTRFS_EXTENT_ITEM_KEY &&
                    found_key.type != BTRFS_METADATA_ITEM_KEY)
@@ -10937,11 +10924,11 @@ static int build_roots_info_cache(struct btrfs_fs_info *info)
                        rii->node_count++;
                }
 next:
-               path->slots[0]++;
+               path.slots[0]++;
        }
 
 out:
-       btrfs_free_path(path);
+       btrfs_release_path(&path);
 
        return ret;
 }
@@ -11037,7 +11024,7 @@ static int maybe_repair_root_item(struct btrfs_fs_info *info,
  */
 static int repair_root_items(struct btrfs_fs_info *info)
 {
-       struct btrfs_path *path = NULL;
+       struct btrfs_path path;
        struct btrfs_key key;
        struct extent_buffer *leaf;
        struct btrfs_trans_handle *trans = NULL;
@@ -11045,16 +11032,12 @@ static int repair_root_items(struct btrfs_fs_info *info)
        int bad_roots = 0;
        int need_trans = 0;
 
+       btrfs_init_path(&path);
+
        ret = build_roots_info_cache(info);
        if (ret)
                goto out;
 
-       path = btrfs_alloc_path();
-       if (!path) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
        key.objectid = BTRFS_FIRST_FREE_OBJECTID;
        key.type = BTRFS_ROOT_ITEM_KEY;
        key.offset = 0;
@@ -11073,19 +11056,19 @@ again:
                }
        }
 
-       ret = btrfs_search_slot(trans, info->tree_root, &key, path,
+       ret = btrfs_search_slot(trans, info->tree_root, &key, &path,
                                0, trans ? 1 : 0);
        if (ret < 0)
                goto out;
-       leaf = path->nodes[0];
+       leaf = path.nodes[0];
 
        while (1) {
                struct btrfs_key found_key;
 
-               if (path->slots[0] >= btrfs_header_nritems(leaf)) {
-                       int no_more_keys = find_next_key(path, &key);
+               if (path.slots[0] >= btrfs_header_nritems(leaf)) {
+                       int no_more_keys = find_next_key(&path, &key);
 
-                       btrfs_release_path(path);
+                       btrfs_release_path(&path);
                        if (trans) {
                                ret = btrfs_commit_transaction(trans,
                                                               info->tree_root);
@@ -11099,14 +11082,14 @@ again:
                        goto again;
                }
 
-               btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
+               btrfs_item_key_to_cpu(leaf, &found_key, path.slots[0]);
 
                if (found_key.type != BTRFS_ROOT_ITEM_KEY)
                        goto next;
                if (found_key.objectid == BTRFS_TREE_RELOC_OBJECTID)
                        goto next;
 
-               ret = maybe_repair_root_item(info, path, &found_key,
+               ret = maybe_repair_root_item(info, &path, &found_key,
                                             trans ? 0 : 1);
                if (ret < 0)
                        goto out;
@@ -11114,18 +11097,18 @@ again:
                        if (!trans && repair) {
                                need_trans = 1;
                                key = found_key;
-                               btrfs_release_path(path);
+                               btrfs_release_path(&path);
                                goto again;
                        }
                        bad_roots++;
                }
 next:
-               path->slots[0]++;
+               path.slots[0]++;
        }
        ret = 0;
 out:
        free_roots_info_cache();
-       btrfs_free_path(path);
+       btrfs_release_path(&path);
        if (trans)
                btrfs_commit_transaction(trans, info->tree_root);
        if (ret < 0)