^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2015 Facebook. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "btrfs-tests.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "../ctree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "../disk-io.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "../free-space-tree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "../transaction.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "../block-group.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) struct free_space_extent {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) u64 start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) u64 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static int __check_free_space_extents(struct btrfs_trans_handle *trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct btrfs_fs_info *fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct btrfs_block_group *cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct btrfs_path *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) const struct free_space_extent * const extents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) unsigned int num_extents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct btrfs_free_space_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct btrfs_key key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) int prev_bit = 0, bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) u64 extent_start = 0, offset, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) u32 flags, extent_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) info = search_free_space_info(trans, cache, path, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) if (IS_ERR(info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) test_err("could not find free space info");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) ret = PTR_ERR(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) flags = btrfs_free_space_flags(path->nodes[0], info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) extent_count = btrfs_free_space_extent_count(path->nodes[0], info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (extent_count != num_extents) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) test_err("extent count is wrong");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (flags & BTRFS_FREE_SPACE_USING_BITMAPS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (path->slots[0] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) goto invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) end = cache->start + cache->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) while (++path->slots[0] < btrfs_header_nritems(path->nodes[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (key.type != BTRFS_FREE_SPACE_BITMAP_KEY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) goto invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) offset = key.objectid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) while (offset < key.objectid + key.offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) bit = free_space_test_bit(cache, path, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (prev_bit == 0 && bit == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) extent_start = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) } else if (prev_bit == 1 && bit == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (i >= num_extents ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) extent_start != extents[i].start ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) offset - extent_start != extents[i].length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) goto invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) prev_bit = bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) offset += fs_info->sectorsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (prev_bit == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (i >= num_extents ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) extent_start != extents[i].start ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) end - extent_start != extents[i].length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) goto invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (i != num_extents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) goto invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (btrfs_header_nritems(path->nodes[0]) != num_extents + 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) path->slots[0] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) goto invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) for (i = 0; i < num_extents; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) path->slots[0]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (key.type != BTRFS_FREE_SPACE_EXTENT_KEY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) key.objectid != extents[i].start ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) key.offset != extents[i].length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) goto invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) btrfs_release_path(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) invalid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) test_err("free space tree is invalid");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static int check_free_space_extents(struct btrfs_trans_handle *trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct btrfs_fs_info *fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct btrfs_block_group *cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct btrfs_path *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) const struct free_space_extent * const extents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) unsigned int num_extents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct btrfs_free_space_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) info = search_free_space_info(trans, cache, path, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (IS_ERR(info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) test_err("could not find free space info");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) btrfs_release_path(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return PTR_ERR(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) flags = btrfs_free_space_flags(path->nodes[0], info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) btrfs_release_path(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ret = __check_free_space_extents(trans, fs_info, cache, path, extents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) num_extents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* Flip it to the other format and check that for good measure. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (flags & BTRFS_FREE_SPACE_USING_BITMAPS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ret = convert_free_space_to_extents(trans, cache, path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) test_err("could not convert to extents");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ret = convert_free_space_to_bitmaps(trans, cache, path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) test_err("could not convert to bitmaps");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return __check_free_space_extents(trans, fs_info, cache, path, extents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) num_extents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static int test_empty_block_group(struct btrfs_trans_handle *trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct btrfs_fs_info *fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct btrfs_block_group *cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct btrfs_path *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u32 alignment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) const struct free_space_extent extents[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {cache->start, cache->length},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return check_free_space_extents(trans, fs_info, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) extents, ARRAY_SIZE(extents));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static int test_remove_all(struct btrfs_trans_handle *trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct btrfs_fs_info *fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct btrfs_block_group *cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct btrfs_path *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) u32 alignment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) const struct free_space_extent extents[] = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) ret = __remove_from_free_space_tree(trans, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) cache->start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) cache->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) test_err("could not remove free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return check_free_space_extents(trans, fs_info, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) extents, ARRAY_SIZE(extents));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static int test_remove_beginning(struct btrfs_trans_handle *trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct btrfs_fs_info *fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct btrfs_block_group *cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct btrfs_path *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) u32 alignment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) const struct free_space_extent extents[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {cache->start + alignment, cache->length - alignment},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) ret = __remove_from_free_space_tree(trans, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) cache->start, alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) test_err("could not remove free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return check_free_space_extents(trans, fs_info, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) extents, ARRAY_SIZE(extents));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static int test_remove_end(struct btrfs_trans_handle *trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct btrfs_fs_info *fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct btrfs_block_group *cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct btrfs_path *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) u32 alignment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) const struct free_space_extent extents[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {cache->start, cache->length - alignment},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ret = __remove_from_free_space_tree(trans, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) cache->start + cache->length - alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) test_err("could not remove free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return check_free_space_extents(trans, fs_info, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) extents, ARRAY_SIZE(extents));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static int test_remove_middle(struct btrfs_trans_handle *trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct btrfs_fs_info *fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct btrfs_block_group *cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct btrfs_path *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) u32 alignment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) const struct free_space_extent extents[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {cache->start, alignment},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {cache->start + 2 * alignment, cache->length - 2 * alignment},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) ret = __remove_from_free_space_tree(trans, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) cache->start + alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) test_err("could not remove free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return check_free_space_extents(trans, fs_info, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) extents, ARRAY_SIZE(extents));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static int test_merge_left(struct btrfs_trans_handle *trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct btrfs_fs_info *fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct btrfs_block_group *cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct btrfs_path *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) u32 alignment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) const struct free_space_extent extents[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {cache->start, 2 * alignment},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ret = __remove_from_free_space_tree(trans, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) cache->start, cache->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) test_err("could not remove free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) ret = __add_to_free_space_tree(trans, cache, path, cache->start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) test_err("could not add free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ret = __add_to_free_space_tree(trans, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) cache->start + alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) test_err("could not add free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return check_free_space_extents(trans, fs_info, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) extents, ARRAY_SIZE(extents));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static int test_merge_right(struct btrfs_trans_handle *trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct btrfs_fs_info *fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct btrfs_block_group *cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct btrfs_path *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) u32 alignment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) const struct free_space_extent extents[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {cache->start + alignment, 2 * alignment},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ret = __remove_from_free_space_tree(trans, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) cache->start, cache->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) test_err("could not remove free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ret = __add_to_free_space_tree(trans, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) cache->start + 2 * alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) test_err("could not add free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) ret = __add_to_free_space_tree(trans, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) cache->start + alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) test_err("could not add free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return check_free_space_extents(trans, fs_info, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) extents, ARRAY_SIZE(extents));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static int test_merge_both(struct btrfs_trans_handle *trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct btrfs_fs_info *fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct btrfs_block_group *cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct btrfs_path *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) u32 alignment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) const struct free_space_extent extents[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {cache->start, 3 * alignment},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) ret = __remove_from_free_space_tree(trans, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) cache->start, cache->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) test_err("could not remove free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ret = __add_to_free_space_tree(trans, cache, path, cache->start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) test_err("could not add free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ret = __add_to_free_space_tree(trans, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) cache->start + 2 * alignment, alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) test_err("could not add free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) ret = __add_to_free_space_tree(trans, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) cache->start + alignment, alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) test_err("could not add free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return check_free_space_extents(trans, fs_info, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) extents, ARRAY_SIZE(extents));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static int test_merge_none(struct btrfs_trans_handle *trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct btrfs_fs_info *fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct btrfs_block_group *cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct btrfs_path *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) u32 alignment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) const struct free_space_extent extents[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {cache->start, alignment},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {cache->start + 2 * alignment, alignment},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {cache->start + 4 * alignment, alignment},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) ret = __remove_from_free_space_tree(trans, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) cache->start, cache->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) test_err("could not remove free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) ret = __add_to_free_space_tree(trans, cache, path, cache->start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) test_err("could not add free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) ret = __add_to_free_space_tree(trans, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) cache->start + 4 * alignment, alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) test_err("could not add free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) ret = __add_to_free_space_tree(trans, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) cache->start + 2 * alignment, alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) test_err("could not add free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return check_free_space_extents(trans, fs_info, cache, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) extents, ARRAY_SIZE(extents));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) typedef int (*test_func_t)(struct btrfs_trans_handle *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) struct btrfs_fs_info *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) struct btrfs_block_group *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct btrfs_path *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) u32 alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static int run_test(test_func_t test_func, int bitmaps, u32 sectorsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) u32 nodesize, u32 alignment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct btrfs_fs_info *fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct btrfs_root *root = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct btrfs_block_group *cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct btrfs_trans_handle trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct btrfs_path *path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (!fs_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) test_std_err(TEST_ALLOC_FS_INFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) root = btrfs_alloc_dummy_root(fs_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (IS_ERR(root)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) test_std_err(TEST_ALLOC_ROOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) ret = PTR_ERR(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) btrfs_set_super_compat_ro_flags(root->fs_info->super_copy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) root->fs_info->free_space_root = root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) root->fs_info->tree_root = root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) root->node = alloc_test_extent_buffer(root->fs_info, nodesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (IS_ERR(root->node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) test_std_err(TEST_ALLOC_EXTENT_BUFFER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) ret = PTR_ERR(root->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) btrfs_set_header_level(root->node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) btrfs_set_header_nritems(root->node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) root->alloc_bytenr += 2 * nodesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) cache = btrfs_alloc_dummy_block_group(fs_info, 8 * alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (!cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) test_std_err(TEST_ALLOC_BLOCK_GROUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) cache->bitmap_low_thresh = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) cache->bitmap_high_thresh = (u32)-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) cache->needs_free_space = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) cache->fs_info = root->fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) btrfs_init_dummy_trans(&trans, root->fs_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) path = btrfs_alloc_path();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (!path) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) test_std_err(TEST_ALLOC_ROOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ret = add_block_group_free_space(&trans, cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) test_err("could not add block group free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (bitmaps) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) ret = convert_free_space_to_bitmaps(&trans, cache, path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) test_err("could not convert block group to bitmaps");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ret = test_func(&trans, root->fs_info, cache, path, alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ret = remove_block_group_free_space(&trans, cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) test_err("could not remove block group free space");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (btrfs_header_nritems(root->node) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) test_err("free space tree has leftover items");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) btrfs_free_path(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) btrfs_free_dummy_block_group(cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) btrfs_free_dummy_root(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) btrfs_free_dummy_fs_info(fs_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static int run_test_both_formats(test_func_t test_func, u32 sectorsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) u32 nodesize, u32 alignment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) int test_ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) ret = run_test(test_func, 0, sectorsize, nodesize, alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) test_err(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) "%ps failed with extents, sectorsize=%u, nodesize=%u, alignment=%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) test_func, sectorsize, nodesize, alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) test_ret = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ret = run_test(test_func, 1, sectorsize, nodesize, alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) test_err(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) "%ps failed with bitmaps, sectorsize=%u, nodesize=%u, alignment=%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) test_func, sectorsize, nodesize, alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) test_ret = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return test_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) int btrfs_test_free_space_tree(u32 sectorsize, u32 nodesize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) test_func_t tests[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) test_empty_block_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) test_remove_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) test_remove_beginning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) test_remove_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) test_remove_middle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) test_merge_left,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) test_merge_right,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) test_merge_both,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) test_merge_none,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) u32 bitmap_alignment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) int test_ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * Align some operations to a page to flush out bugs in the extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * buffer bitmap handling of highmem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) bitmap_alignment = BTRFS_FREE_SPACE_BITMAP_BITS * PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) test_msg("running free space tree tests");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) for (i = 0; i < ARRAY_SIZE(tests); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) ret = run_test_both_formats(tests[i], sectorsize, nodesize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) test_ret = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) ret = run_test_both_formats(tests[i], sectorsize, nodesize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) bitmap_alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) test_ret = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return test_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }