1c1d7c514SDavid Sterba // SPDX-License-Identifier: GPL-2.0 2dc11dd5dSJosef Bacik /* 3dc11dd5dSJosef Bacik * Copyright (C) 2013 Fusion IO. All rights reserved. 4dc11dd5dSJosef Bacik */ 5dc11dd5dSJosef Bacik 6dc11dd5dSJosef Bacik #include <linux/slab.h> 7dc11dd5dSJosef Bacik #include "btrfs-tests.h" 8dc11dd5dSJosef Bacik #include "../ctree.h" 9d0bd4560SJosef Bacik #include "../disk-io.h" 10dc11dd5dSJosef Bacik #include "../free-space-cache.h" 11aac0023cSJosef Bacik #include "../block-group.h" 12dc11dd5dSJosef Bacik 130ef6447aSFeifei Xu #define BITS_PER_BITMAP (PAGE_SIZE * 8UL) 14dc11dd5dSJosef Bacik 15dc11dd5dSJosef Bacik /* 1601327610SNicholas D Steeves * This test just does basic sanity checking, making sure we can add an extent 17dc11dd5dSJosef Bacik * entry and remove space from either end and the middle, and make sure we can 18dc11dd5dSJosef Bacik * remove space that covers adjacent extent entries. 19dc11dd5dSJosef Bacik */ 2032da5386SDavid Sterba static int test_extents(struct btrfs_block_group *cache) 21dc11dd5dSJosef Bacik { 22dc11dd5dSJosef Bacik int ret = 0; 23dc11dd5dSJosef Bacik 24315b76b4SDavid Sterba test_msg("running extent only tests"); 25dc11dd5dSJosef Bacik 26dc11dd5dSJosef Bacik /* First just make sure we can remove an entire entry */ 27ee22184bSByongho Lee ret = btrfs_add_free_space(cache, 0, SZ_4M); 28dc11dd5dSJosef Bacik if (ret) { 293c7251f2SDavid Sterba test_err("error adding initial extents %d", ret); 30dc11dd5dSJosef Bacik return ret; 31dc11dd5dSJosef Bacik } 32dc11dd5dSJosef Bacik 33ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, 0, SZ_4M); 34dc11dd5dSJosef Bacik if (ret) { 353c7251f2SDavid Sterba test_err("error removing extent %d", ret); 36dc11dd5dSJosef Bacik return ret; 37dc11dd5dSJosef Bacik } 38dc11dd5dSJosef Bacik 39ee22184bSByongho Lee if (test_check_exists(cache, 0, SZ_4M)) { 403c7251f2SDavid Sterba test_err("full remove left some lingering space"); 41dc11dd5dSJosef Bacik return -1; 42dc11dd5dSJosef Bacik } 43dc11dd5dSJosef Bacik 44dc11dd5dSJosef Bacik /* Ok edge and middle cases now */ 45ee22184bSByongho Lee ret = btrfs_add_free_space(cache, 0, SZ_4M); 46dc11dd5dSJosef Bacik if (ret) { 473c7251f2SDavid Sterba test_err("error adding half extent %d", ret); 48dc11dd5dSJosef Bacik return ret; 49dc11dd5dSJosef Bacik } 50dc11dd5dSJosef Bacik 51ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, 3 * SZ_1M, SZ_1M); 52dc11dd5dSJosef Bacik if (ret) { 533c7251f2SDavid Sterba test_err("error removing tail end %d", ret); 54dc11dd5dSJosef Bacik return ret; 55dc11dd5dSJosef Bacik } 56dc11dd5dSJosef Bacik 57ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, 0, SZ_1M); 58dc11dd5dSJosef Bacik if (ret) { 593c7251f2SDavid Sterba test_err("error removing front end %d", ret); 60dc11dd5dSJosef Bacik return ret; 61dc11dd5dSJosef Bacik } 62dc11dd5dSJosef Bacik 63ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, SZ_2M, 4096); 64dc11dd5dSJosef Bacik if (ret) { 653c7251f2SDavid Sterba test_err("error removing middle piece %d", ret); 66dc11dd5dSJosef Bacik return ret; 67dc11dd5dSJosef Bacik } 68dc11dd5dSJosef Bacik 69ee22184bSByongho Lee if (test_check_exists(cache, 0, SZ_1M)) { 703c7251f2SDavid Sterba test_err("still have space at the front"); 71dc11dd5dSJosef Bacik return -1; 72dc11dd5dSJosef Bacik } 73dc11dd5dSJosef Bacik 74ee22184bSByongho Lee if (test_check_exists(cache, SZ_2M, 4096)) { 753c7251f2SDavid Sterba test_err("still have space in the middle"); 76dc11dd5dSJosef Bacik return -1; 77dc11dd5dSJosef Bacik } 78dc11dd5dSJosef Bacik 79ee22184bSByongho Lee if (test_check_exists(cache, 3 * SZ_1M, SZ_1M)) { 803c7251f2SDavid Sterba test_err("still have space at the end"); 81dc11dd5dSJosef Bacik return -1; 82dc11dd5dSJosef Bacik } 83dc11dd5dSJosef Bacik 84dc11dd5dSJosef Bacik /* Cleanup */ 85dc11dd5dSJosef Bacik __btrfs_remove_free_space_cache(cache->free_space_ctl); 86dc11dd5dSJosef Bacik 87dc11dd5dSJosef Bacik return 0; 88dc11dd5dSJosef Bacik } 89dc11dd5dSJosef Bacik 9032da5386SDavid Sterba static int test_bitmaps(struct btrfs_block_group *cache, u32 sectorsize) 91dc11dd5dSJosef Bacik { 92dc11dd5dSJosef Bacik u64 next_bitmap_offset; 93dc11dd5dSJosef Bacik int ret; 94dc11dd5dSJosef Bacik 95315b76b4SDavid Sterba test_msg("running bitmap only tests"); 96dc11dd5dSJosef Bacik 97ee22184bSByongho Lee ret = test_add_free_space_entry(cache, 0, SZ_4M, 1); 98dc11dd5dSJosef Bacik if (ret) { 993c7251f2SDavid Sterba test_err("couldn't create a bitmap entry %d", ret); 100dc11dd5dSJosef Bacik return ret; 101dc11dd5dSJosef Bacik } 102dc11dd5dSJosef Bacik 103ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, 0, SZ_4M); 104dc11dd5dSJosef Bacik if (ret) { 1053c7251f2SDavid Sterba test_err("error removing bitmap full range %d", ret); 106dc11dd5dSJosef Bacik return ret; 107dc11dd5dSJosef Bacik } 108dc11dd5dSJosef Bacik 109ee22184bSByongho Lee if (test_check_exists(cache, 0, SZ_4M)) { 1103c7251f2SDavid Sterba test_err("left some space in bitmap"); 111dc11dd5dSJosef Bacik return -1; 112dc11dd5dSJosef Bacik } 113dc11dd5dSJosef Bacik 114ee22184bSByongho Lee ret = test_add_free_space_entry(cache, 0, SZ_4M, 1); 115dc11dd5dSJosef Bacik if (ret) { 1163c7251f2SDavid Sterba test_err("couldn't add to our bitmap entry %d", ret); 117dc11dd5dSJosef Bacik return ret; 118dc11dd5dSJosef Bacik } 119dc11dd5dSJosef Bacik 120ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, SZ_1M, SZ_2M); 121dc11dd5dSJosef Bacik if (ret) { 1223c7251f2SDavid Sterba test_err("couldn't remove middle chunk %d", ret); 123dc11dd5dSJosef Bacik return ret; 124dc11dd5dSJosef Bacik } 125dc11dd5dSJosef Bacik 126dc11dd5dSJosef Bacik /* 127dc11dd5dSJosef Bacik * The first bitmap we have starts at offset 0 so the next one is just 128dc11dd5dSJosef Bacik * at the end of the first bitmap. 129dc11dd5dSJosef Bacik */ 130b9ef22deSFeifei Xu next_bitmap_offset = (u64)(BITS_PER_BITMAP * sectorsize); 131dc11dd5dSJosef Bacik 132dc11dd5dSJosef Bacik /* Test a bit straddling two bitmaps */ 133ee22184bSByongho Lee ret = test_add_free_space_entry(cache, next_bitmap_offset - SZ_2M, 134ee22184bSByongho Lee SZ_4M, 1); 135dc11dd5dSJosef Bacik if (ret) { 1363c7251f2SDavid Sterba test_err("couldn't add space that straddles two bitmaps %d", 137dc11dd5dSJosef Bacik ret); 138dc11dd5dSJosef Bacik return ret; 139dc11dd5dSJosef Bacik } 140dc11dd5dSJosef Bacik 141ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, next_bitmap_offset - SZ_1M, SZ_2M); 142dc11dd5dSJosef Bacik if (ret) { 1433c7251f2SDavid Sterba test_err("couldn't remove overlapping space %d", ret); 144dc11dd5dSJosef Bacik return ret; 145dc11dd5dSJosef Bacik } 146dc11dd5dSJosef Bacik 147ee22184bSByongho Lee if (test_check_exists(cache, next_bitmap_offset - SZ_1M, SZ_2M)) { 1483c7251f2SDavid Sterba test_err("left some space when removing overlapping"); 149dc11dd5dSJosef Bacik return -1; 150dc11dd5dSJosef Bacik } 151dc11dd5dSJosef Bacik 152dc11dd5dSJosef Bacik __btrfs_remove_free_space_cache(cache->free_space_ctl); 153dc11dd5dSJosef Bacik 154dc11dd5dSJosef Bacik return 0; 155dc11dd5dSJosef Bacik } 156dc11dd5dSJosef Bacik 157dc11dd5dSJosef Bacik /* This is the high grade jackassery */ 15832da5386SDavid Sterba static int test_bitmaps_and_extents(struct btrfs_block_group *cache, 159b9ef22deSFeifei Xu u32 sectorsize) 160dc11dd5dSJosef Bacik { 161b9ef22deSFeifei Xu u64 bitmap_offset = (u64)(BITS_PER_BITMAP * sectorsize); 162dc11dd5dSJosef Bacik int ret; 163dc11dd5dSJosef Bacik 164315b76b4SDavid Sterba test_msg("running bitmap and extent tests"); 165dc11dd5dSJosef Bacik 166dc11dd5dSJosef Bacik /* 167dc11dd5dSJosef Bacik * First let's do something simple, an extent at the same offset as the 168dc11dd5dSJosef Bacik * bitmap, but the free space completely in the extent and then 169dc11dd5dSJosef Bacik * completely in the bitmap. 170dc11dd5dSJosef Bacik */ 171ee22184bSByongho Lee ret = test_add_free_space_entry(cache, SZ_4M, SZ_1M, 1); 172dc11dd5dSJosef Bacik if (ret) { 1733c7251f2SDavid Sterba test_err("couldn't create bitmap entry %d", ret); 174dc11dd5dSJosef Bacik return ret; 175dc11dd5dSJosef Bacik } 176dc11dd5dSJosef Bacik 177ee22184bSByongho Lee ret = test_add_free_space_entry(cache, 0, SZ_1M, 0); 178dc11dd5dSJosef Bacik if (ret) { 1793c7251f2SDavid Sterba test_err("couldn't add extent entry %d", ret); 180dc11dd5dSJosef Bacik return ret; 181dc11dd5dSJosef Bacik } 182dc11dd5dSJosef Bacik 183ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, 0, SZ_1M); 184dc11dd5dSJosef Bacik if (ret) { 1853c7251f2SDavid Sterba test_err("couldn't remove extent entry %d", ret); 186dc11dd5dSJosef Bacik return ret; 187dc11dd5dSJosef Bacik } 188dc11dd5dSJosef Bacik 189ee22184bSByongho Lee if (test_check_exists(cache, 0, SZ_1M)) { 1903c7251f2SDavid Sterba test_err("left remnants after our remove"); 191dc11dd5dSJosef Bacik return -1; 192dc11dd5dSJosef Bacik } 193dc11dd5dSJosef Bacik 194dc11dd5dSJosef Bacik /* Now to add back the extent entry and remove from the bitmap */ 195ee22184bSByongho Lee ret = test_add_free_space_entry(cache, 0, SZ_1M, 0); 196dc11dd5dSJosef Bacik if (ret) { 1973c7251f2SDavid Sterba test_err("couldn't re-add extent entry %d", ret); 198dc11dd5dSJosef Bacik return ret; 199dc11dd5dSJosef Bacik } 200dc11dd5dSJosef Bacik 201ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, SZ_4M, SZ_1M); 202dc11dd5dSJosef Bacik if (ret) { 2033c7251f2SDavid Sterba test_err("couldn't remove from bitmap %d", ret); 204dc11dd5dSJosef Bacik return ret; 205dc11dd5dSJosef Bacik } 206dc11dd5dSJosef Bacik 207ee22184bSByongho Lee if (test_check_exists(cache, SZ_4M, SZ_1M)) { 2083c7251f2SDavid Sterba test_err("left remnants in the bitmap"); 209dc11dd5dSJosef Bacik return -1; 210dc11dd5dSJosef Bacik } 211dc11dd5dSJosef Bacik 212dc11dd5dSJosef Bacik /* 213dc11dd5dSJosef Bacik * Ok so a little more evil, extent entry and bitmap at the same offset, 214dc11dd5dSJosef Bacik * removing an overlapping chunk. 215dc11dd5dSJosef Bacik */ 216ee22184bSByongho Lee ret = test_add_free_space_entry(cache, SZ_1M, SZ_4M, 1); 217dc11dd5dSJosef Bacik if (ret) { 2183c7251f2SDavid Sterba test_err("couldn't add to a bitmap %d", ret); 219dc11dd5dSJosef Bacik return ret; 220dc11dd5dSJosef Bacik } 221dc11dd5dSJosef Bacik 222ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, SZ_512K, 3 * SZ_1M); 223dc11dd5dSJosef Bacik if (ret) { 2243c7251f2SDavid Sterba test_err("couldn't remove overlapping space %d", ret); 225dc11dd5dSJosef Bacik return ret; 226dc11dd5dSJosef Bacik } 227dc11dd5dSJosef Bacik 228ee22184bSByongho Lee if (test_check_exists(cache, SZ_512K, 3 * SZ_1M)) { 2293c7251f2SDavid Sterba test_err("left over pieces after removing overlapping"); 230dc11dd5dSJosef Bacik return -1; 231dc11dd5dSJosef Bacik } 232dc11dd5dSJosef Bacik 233dc11dd5dSJosef Bacik __btrfs_remove_free_space_cache(cache->free_space_ctl); 234dc11dd5dSJosef Bacik 235dc11dd5dSJosef Bacik /* Now with the extent entry offset into the bitmap */ 236ee22184bSByongho Lee ret = test_add_free_space_entry(cache, SZ_4M, SZ_4M, 1); 237dc11dd5dSJosef Bacik if (ret) { 2383c7251f2SDavid Sterba test_err("couldn't add space to the bitmap %d", ret); 239dc11dd5dSJosef Bacik return ret; 240dc11dd5dSJosef Bacik } 241dc11dd5dSJosef Bacik 242ee22184bSByongho Lee ret = test_add_free_space_entry(cache, SZ_2M, SZ_2M, 0); 243dc11dd5dSJosef Bacik if (ret) { 2443c7251f2SDavid Sterba test_err("couldn't add extent to the cache %d", ret); 245dc11dd5dSJosef Bacik return ret; 246dc11dd5dSJosef Bacik } 247dc11dd5dSJosef Bacik 248ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, 3 * SZ_1M, SZ_4M); 249dc11dd5dSJosef Bacik if (ret) { 2503c7251f2SDavid Sterba test_err("problem removing overlapping space %d", ret); 251dc11dd5dSJosef Bacik return ret; 252dc11dd5dSJosef Bacik } 253dc11dd5dSJosef Bacik 254ee22184bSByongho Lee if (test_check_exists(cache, 3 * SZ_1M, SZ_4M)) { 2553c7251f2SDavid Sterba test_err("left something behind when removing space"); 256dc11dd5dSJosef Bacik return -1; 257dc11dd5dSJosef Bacik } 258dc11dd5dSJosef Bacik 259dc11dd5dSJosef Bacik /* 260dc11dd5dSJosef Bacik * This has blown up in the past, the extent entry starts before the 261dc11dd5dSJosef Bacik * bitmap entry, but we're trying to remove an offset that falls 262dc11dd5dSJosef Bacik * completely within the bitmap range and is in both the extent entry 263dc11dd5dSJosef Bacik * and the bitmap entry, looks like this 264dc11dd5dSJosef Bacik * 265dc11dd5dSJosef Bacik * [ extent ] 266dc11dd5dSJosef Bacik * [ bitmap ] 267dc11dd5dSJosef Bacik * [ del ] 268dc11dd5dSJosef Bacik */ 269dc11dd5dSJosef Bacik __btrfs_remove_free_space_cache(cache->free_space_ctl); 270ee22184bSByongho Lee ret = test_add_free_space_entry(cache, bitmap_offset + SZ_4M, SZ_4M, 1); 271dc11dd5dSJosef Bacik if (ret) { 2723c7251f2SDavid Sterba test_err("couldn't add bitmap %d", ret); 273dc11dd5dSJosef Bacik return ret; 274dc11dd5dSJosef Bacik } 275dc11dd5dSJosef Bacik 276ee22184bSByongho Lee ret = test_add_free_space_entry(cache, bitmap_offset - SZ_1M, 277ee22184bSByongho Lee 5 * SZ_1M, 0); 278dc11dd5dSJosef Bacik if (ret) { 2793c7251f2SDavid Sterba test_err("couldn't add extent entry %d", ret); 280dc11dd5dSJosef Bacik return ret; 281dc11dd5dSJosef Bacik } 282dc11dd5dSJosef Bacik 283ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, bitmap_offset + SZ_1M, 5 * SZ_1M); 284dc11dd5dSJosef Bacik if (ret) { 2853c7251f2SDavid Sterba test_err("failed to free our space %d", ret); 286dc11dd5dSJosef Bacik return ret; 287dc11dd5dSJosef Bacik } 288dc11dd5dSJosef Bacik 289ee22184bSByongho Lee if (test_check_exists(cache, bitmap_offset + SZ_1M, 5 * SZ_1M)) { 2903c7251f2SDavid Sterba test_err("left stuff over"); 291dc11dd5dSJosef Bacik return -1; 292dc11dd5dSJosef Bacik } 293dc11dd5dSJosef Bacik 294dc11dd5dSJosef Bacik __btrfs_remove_free_space_cache(cache->free_space_ctl); 295dc11dd5dSJosef Bacik 296dc11dd5dSJosef Bacik /* 297dc11dd5dSJosef Bacik * This blew up before, we have part of the free space in a bitmap and 298dc11dd5dSJosef Bacik * then the entirety of the rest of the space in an extent. This used 299dc11dd5dSJosef Bacik * to return -EAGAIN back from btrfs_remove_extent, make sure this 300dc11dd5dSJosef Bacik * doesn't happen. 301dc11dd5dSJosef Bacik */ 302ee22184bSByongho Lee ret = test_add_free_space_entry(cache, SZ_1M, SZ_2M, 1); 303dc11dd5dSJosef Bacik if (ret) { 3043c7251f2SDavid Sterba test_err("couldn't add bitmap entry %d", ret); 305dc11dd5dSJosef Bacik return ret; 306dc11dd5dSJosef Bacik } 307dc11dd5dSJosef Bacik 308ee22184bSByongho Lee ret = test_add_free_space_entry(cache, 3 * SZ_1M, SZ_1M, 0); 309dc11dd5dSJosef Bacik if (ret) { 3103c7251f2SDavid Sterba test_err("couldn't add extent entry %d", ret); 311dc11dd5dSJosef Bacik return ret; 312dc11dd5dSJosef Bacik } 313dc11dd5dSJosef Bacik 314ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, SZ_1M, 3 * SZ_1M); 315dc11dd5dSJosef Bacik if (ret) { 3163c7251f2SDavid Sterba test_err("error removing bitmap and extent overlapping %d", ret); 317dc11dd5dSJosef Bacik return ret; 318dc11dd5dSJosef Bacik } 319dc11dd5dSJosef Bacik 320dc11dd5dSJosef Bacik __btrfs_remove_free_space_cache(cache->free_space_ctl); 321dc11dd5dSJosef Bacik return 0; 322dc11dd5dSJosef Bacik } 323dc11dd5dSJosef Bacik 32420005523SFilipe Manana /* Used by test_steal_space_from_bitmap_to_extent(). */ 32520005523SFilipe Manana static bool test_use_bitmap(struct btrfs_free_space_ctl *ctl, 32620005523SFilipe Manana struct btrfs_free_space *info) 32720005523SFilipe Manana { 32820005523SFilipe Manana return ctl->free_extents > 0; 32920005523SFilipe Manana } 33020005523SFilipe Manana 33120005523SFilipe Manana /* Used by test_steal_space_from_bitmap_to_extent(). */ 33220005523SFilipe Manana static int 33332da5386SDavid Sterba check_num_extents_and_bitmaps(const struct btrfs_block_group *cache, 33420005523SFilipe Manana const int num_extents, 33520005523SFilipe Manana const int num_bitmaps) 33620005523SFilipe Manana { 33720005523SFilipe Manana if (cache->free_space_ctl->free_extents != num_extents) { 3383c7251f2SDavid Sterba test_err( 3393c7251f2SDavid Sterba "incorrect # of extent entries in the cache: %d, expected %d", 34020005523SFilipe Manana cache->free_space_ctl->free_extents, num_extents); 34120005523SFilipe Manana return -EINVAL; 34220005523SFilipe Manana } 34320005523SFilipe Manana if (cache->free_space_ctl->total_bitmaps != num_bitmaps) { 3443c7251f2SDavid Sterba test_err( 3453c7251f2SDavid Sterba "incorrect # of extent entries in the cache: %d, expected %d", 34620005523SFilipe Manana cache->free_space_ctl->total_bitmaps, num_bitmaps); 34720005523SFilipe Manana return -EINVAL; 34820005523SFilipe Manana } 34920005523SFilipe Manana return 0; 35020005523SFilipe Manana } 35120005523SFilipe Manana 35220005523SFilipe Manana /* Used by test_steal_space_from_bitmap_to_extent(). */ 35332da5386SDavid Sterba static int check_cache_empty(struct btrfs_block_group *cache) 35420005523SFilipe Manana { 35520005523SFilipe Manana u64 offset; 35620005523SFilipe Manana u64 max_extent_size; 35720005523SFilipe Manana 35820005523SFilipe Manana /* 35920005523SFilipe Manana * Now lets confirm that there's absolutely no free space left to 36020005523SFilipe Manana * allocate. 36120005523SFilipe Manana */ 36220005523SFilipe Manana if (cache->free_space_ctl->free_space != 0) { 3633c7251f2SDavid Sterba test_err("cache free space is not 0"); 36420005523SFilipe Manana return -EINVAL; 36520005523SFilipe Manana } 36620005523SFilipe Manana 36720005523SFilipe Manana /* And any allocation request, no matter how small, should fail now. */ 36820005523SFilipe Manana offset = btrfs_find_space_for_alloc(cache, 0, 4096, 0, 36920005523SFilipe Manana &max_extent_size); 37020005523SFilipe Manana if (offset != 0) { 3713c7251f2SDavid Sterba test_err("space allocation did not fail, returned offset: %llu", 37220005523SFilipe Manana offset); 37320005523SFilipe Manana return -EINVAL; 37420005523SFilipe Manana } 37520005523SFilipe Manana 37620005523SFilipe Manana /* And no extent nor bitmap entries in the cache anymore. */ 37720005523SFilipe Manana return check_num_extents_and_bitmaps(cache, 0, 0); 37820005523SFilipe Manana } 37920005523SFilipe Manana 38020005523SFilipe Manana /* 38120005523SFilipe Manana * Before we were able to steal free space from a bitmap entry to an extent 38220005523SFilipe Manana * entry, we could end up with 2 entries representing a contiguous free space. 38320005523SFilipe Manana * One would be an extent entry and the other a bitmap entry. Since in order 38420005523SFilipe Manana * to allocate space to a caller we use only 1 entry, we couldn't return that 38520005523SFilipe Manana * whole range to the caller if it was requested. This forced the caller to 38620005523SFilipe Manana * either assume ENOSPC or perform several smaller space allocations, which 38720005523SFilipe Manana * wasn't optimal as they could be spread all over the block group while under 38820005523SFilipe Manana * concurrency (extra overhead and fragmentation). 38920005523SFilipe Manana * 39001327610SNicholas D Steeves * This stealing approach is beneficial, since we always prefer to allocate 39101327610SNicholas D Steeves * from extent entries, both for clustered and non-clustered allocation 39201327610SNicholas D Steeves * requests. 39320005523SFilipe Manana */ 39420005523SFilipe Manana static int 39532da5386SDavid Sterba test_steal_space_from_bitmap_to_extent(struct btrfs_block_group *cache, 396b9ef22deSFeifei Xu u32 sectorsize) 39720005523SFilipe Manana { 39820005523SFilipe Manana int ret; 39920005523SFilipe Manana u64 offset; 40020005523SFilipe Manana u64 max_extent_size; 40120e5506bSDavid Sterba const struct btrfs_free_space_op test_free_space_ops = { 40228f0779aSDavid Sterba .use_bitmap = test_use_bitmap, 40328f0779aSDavid Sterba }; 40420e5506bSDavid Sterba const struct btrfs_free_space_op *orig_free_space_ops; 40520005523SFilipe Manana 406e4fa7469SDavid Sterba test_msg("running space stealing from bitmap to extent tests"); 40720005523SFilipe Manana 40820005523SFilipe Manana /* 40920005523SFilipe Manana * For this test, we want to ensure we end up with an extent entry 41020005523SFilipe Manana * immediately adjacent to a bitmap entry, where the bitmap starts 41120005523SFilipe Manana * at an offset where the extent entry ends. We keep adding and 41220005523SFilipe Manana * removing free space to reach into this state, but to get there 41320005523SFilipe Manana * we need to reach a point where marking new free space doesn't 41420005523SFilipe Manana * result in adding new extent entries or merging the new space 41520005523SFilipe Manana * with existing extent entries - the space ends up being marked 41620005523SFilipe Manana * in an existing bitmap that covers the new free space range. 41720005523SFilipe Manana * 41820005523SFilipe Manana * To get there, we need to reach the threshold defined set at 41920005523SFilipe Manana * cache->free_space_ctl->extents_thresh, which currently is 42020005523SFilipe Manana * 256 extents on a x86_64 system at least, and a few other 42120005523SFilipe Manana * conditions (check free_space_cache.c). Instead of making the 42220005523SFilipe Manana * test much longer and complicated, use a "use_bitmap" operation 42320005523SFilipe Manana * that forces use of bitmaps as soon as we have at least 1 42420005523SFilipe Manana * extent entry. 42520005523SFilipe Manana */ 42628f0779aSDavid Sterba orig_free_space_ops = cache->free_space_ctl->op; 42728f0779aSDavid Sterba cache->free_space_ctl->op = &test_free_space_ops; 42820005523SFilipe Manana 42920005523SFilipe Manana /* 43020005523SFilipe Manana * Extent entry covering free space range [128Mb - 256Kb, 128Mb - 128Kb[ 43120005523SFilipe Manana */ 432ee22184bSByongho Lee ret = test_add_free_space_entry(cache, SZ_128M - SZ_256K, SZ_128K, 0); 43320005523SFilipe Manana if (ret) { 4343c7251f2SDavid Sterba test_err("couldn't add extent entry %d", ret); 43520005523SFilipe Manana return ret; 43620005523SFilipe Manana } 43720005523SFilipe Manana 43820005523SFilipe Manana /* Bitmap entry covering free space range [128Mb + 512Kb, 256Mb[ */ 439ee22184bSByongho Lee ret = test_add_free_space_entry(cache, SZ_128M + SZ_512K, 440ee22184bSByongho Lee SZ_128M - SZ_512K, 1); 44120005523SFilipe Manana if (ret) { 4423c7251f2SDavid Sterba test_err("couldn't add bitmap entry %d", ret); 44320005523SFilipe Manana return ret; 44420005523SFilipe Manana } 44520005523SFilipe Manana 44620005523SFilipe Manana ret = check_num_extents_and_bitmaps(cache, 2, 1); 44720005523SFilipe Manana if (ret) 44820005523SFilipe Manana return ret; 44920005523SFilipe Manana 45020005523SFilipe Manana /* 45120005523SFilipe Manana * Now make only the first 256Kb of the bitmap marked as free, so that 45220005523SFilipe Manana * we end up with only the following ranges marked as free space: 45320005523SFilipe Manana * 45420005523SFilipe Manana * [128Mb - 256Kb, 128Mb - 128Kb[ 45520005523SFilipe Manana * [128Mb + 512Kb, 128Mb + 768Kb[ 45620005523SFilipe Manana */ 45720005523SFilipe Manana ret = btrfs_remove_free_space(cache, 458ee22184bSByongho Lee SZ_128M + 768 * SZ_1K, 459ee22184bSByongho Lee SZ_128M - 768 * SZ_1K); 46020005523SFilipe Manana if (ret) { 4613c7251f2SDavid Sterba test_err("failed to free part of bitmap space %d", ret); 46220005523SFilipe Manana return ret; 46320005523SFilipe Manana } 46420005523SFilipe Manana 46520005523SFilipe Manana /* Confirm that only those 2 ranges are marked as free. */ 466ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M - SZ_256K, SZ_128K)) { 4673c7251f2SDavid Sterba test_err("free space range missing"); 46820005523SFilipe Manana return -ENOENT; 46920005523SFilipe Manana } 470ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M + SZ_512K, SZ_256K)) { 4713c7251f2SDavid Sterba test_err("free space range missing"); 47220005523SFilipe Manana return -ENOENT; 47320005523SFilipe Manana } 47420005523SFilipe Manana 47520005523SFilipe Manana /* 47620005523SFilipe Manana * Confirm that the bitmap range [128Mb + 768Kb, 256Mb[ isn't marked 47720005523SFilipe Manana * as free anymore. 47820005523SFilipe Manana */ 479ee22184bSByongho Lee if (test_check_exists(cache, SZ_128M + 768 * SZ_1K, 480ee22184bSByongho Lee SZ_128M - 768 * SZ_1K)) { 4813c7251f2SDavid Sterba test_err("bitmap region not removed from space cache"); 48220005523SFilipe Manana return -EINVAL; 48320005523SFilipe Manana } 48420005523SFilipe Manana 48520005523SFilipe Manana /* 48620005523SFilipe Manana * Confirm that the region [128Mb + 256Kb, 128Mb + 512Kb[, which is 48720005523SFilipe Manana * covered by the bitmap, isn't marked as free. 48820005523SFilipe Manana */ 489ee22184bSByongho Lee if (test_check_exists(cache, SZ_128M + SZ_256K, SZ_256K)) { 4903c7251f2SDavid Sterba test_err("invalid bitmap region marked as free"); 49120005523SFilipe Manana return -EINVAL; 49220005523SFilipe Manana } 49320005523SFilipe Manana 49420005523SFilipe Manana /* 49520005523SFilipe Manana * Confirm that the region [128Mb, 128Mb + 256Kb[, which is covered 49620005523SFilipe Manana * by the bitmap too, isn't marked as free either. 49720005523SFilipe Manana */ 498ee22184bSByongho Lee if (test_check_exists(cache, SZ_128M, SZ_256K)) { 4993c7251f2SDavid Sterba test_err("invalid bitmap region marked as free"); 50020005523SFilipe Manana return -EINVAL; 50120005523SFilipe Manana } 50220005523SFilipe Manana 50320005523SFilipe Manana /* 50420005523SFilipe Manana * Now lets mark the region [128Mb, 128Mb + 512Kb[ as free too. But, 50520005523SFilipe Manana * lets make sure the free space cache marks it as free in the bitmap, 50620005523SFilipe Manana * and doesn't insert a new extent entry to represent this region. 50720005523SFilipe Manana */ 508ee22184bSByongho Lee ret = btrfs_add_free_space(cache, SZ_128M, SZ_512K); 50920005523SFilipe Manana if (ret) { 5103c7251f2SDavid Sterba test_err("error adding free space: %d", ret); 51120005523SFilipe Manana return ret; 51220005523SFilipe Manana } 51320005523SFilipe Manana /* Confirm the region is marked as free. */ 514ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M, SZ_512K)) { 5153c7251f2SDavid Sterba test_err("bitmap region not marked as free"); 51620005523SFilipe Manana return -ENOENT; 51720005523SFilipe Manana } 51820005523SFilipe Manana 51920005523SFilipe Manana /* 52020005523SFilipe Manana * Confirm that no new extent entries or bitmap entries were added to 52120005523SFilipe Manana * the cache after adding that free space region. 52220005523SFilipe Manana */ 52320005523SFilipe Manana ret = check_num_extents_and_bitmaps(cache, 2, 1); 52420005523SFilipe Manana if (ret) 52520005523SFilipe Manana return ret; 52620005523SFilipe Manana 52720005523SFilipe Manana /* 52820005523SFilipe Manana * Now lets add a small free space region to the right of the previous 52920005523SFilipe Manana * one, which is not contiguous with it and is part of the bitmap too. 53020005523SFilipe Manana * The goal is to test that the bitmap entry space stealing doesn't 53120005523SFilipe Manana * steal this space region. 53220005523SFilipe Manana */ 533b9ef22deSFeifei Xu ret = btrfs_add_free_space(cache, SZ_128M + SZ_16M, sectorsize); 53420005523SFilipe Manana if (ret) { 5353c7251f2SDavid Sterba test_err("error adding free space: %d", ret); 53620005523SFilipe Manana return ret; 53720005523SFilipe Manana } 53820005523SFilipe Manana 53920005523SFilipe Manana /* 54020005523SFilipe Manana * Confirm that no new extent entries or bitmap entries were added to 54120005523SFilipe Manana * the cache after adding that free space region. 54220005523SFilipe Manana */ 54320005523SFilipe Manana ret = check_num_extents_and_bitmaps(cache, 2, 1); 54420005523SFilipe Manana if (ret) 54520005523SFilipe Manana return ret; 54620005523SFilipe Manana 54720005523SFilipe Manana /* 54820005523SFilipe Manana * Now mark the region [128Mb - 128Kb, 128Mb[ as free too. This will 54920005523SFilipe Manana * expand the range covered by the existing extent entry that represents 55020005523SFilipe Manana * the free space [128Mb - 256Kb, 128Mb - 128Kb[. 55120005523SFilipe Manana */ 552ee22184bSByongho Lee ret = btrfs_add_free_space(cache, SZ_128M - SZ_128K, SZ_128K); 55320005523SFilipe Manana if (ret) { 5543c7251f2SDavid Sterba test_err("error adding free space: %d", ret); 55520005523SFilipe Manana return ret; 55620005523SFilipe Manana } 55720005523SFilipe Manana /* Confirm the region is marked as free. */ 558ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M - SZ_128K, SZ_128K)) { 5593c7251f2SDavid Sterba test_err("extent region not marked as free"); 56020005523SFilipe Manana return -ENOENT; 56120005523SFilipe Manana } 56220005523SFilipe Manana 56320005523SFilipe Manana /* 56420005523SFilipe Manana * Confirm that our extent entry didn't stole all free space from the 56520005523SFilipe Manana * bitmap, because of the small 4Kb free space region. 56620005523SFilipe Manana */ 56720005523SFilipe Manana ret = check_num_extents_and_bitmaps(cache, 2, 1); 56820005523SFilipe Manana if (ret) 56920005523SFilipe Manana return ret; 57020005523SFilipe Manana 57120005523SFilipe Manana /* 57220005523SFilipe Manana * So now we have the range [128Mb - 256Kb, 128Mb + 768Kb[ as free 57320005523SFilipe Manana * space. Without stealing bitmap free space into extent entry space, 57420005523SFilipe Manana * we would have all this free space represented by 2 entries in the 57520005523SFilipe Manana * cache: 57620005523SFilipe Manana * 57720005523SFilipe Manana * extent entry covering range: [128Mb - 256Kb, 128Mb[ 57820005523SFilipe Manana * bitmap entry covering range: [128Mb, 128Mb + 768Kb[ 57920005523SFilipe Manana * 58020005523SFilipe Manana * Attempting to allocate the whole free space (1Mb) would fail, because 58120005523SFilipe Manana * we can't allocate from multiple entries. 58220005523SFilipe Manana * With the bitmap free space stealing, we get a single extent entry 58320005523SFilipe Manana * that represents the 1Mb free space, and therefore we're able to 58420005523SFilipe Manana * allocate the whole free space at once. 58520005523SFilipe Manana */ 586ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M - SZ_256K, SZ_1M)) { 5873c7251f2SDavid Sterba test_err("expected region not marked as free"); 58820005523SFilipe Manana return -ENOENT; 58920005523SFilipe Manana } 59020005523SFilipe Manana 591b9ef22deSFeifei Xu if (cache->free_space_ctl->free_space != (SZ_1M + sectorsize)) { 5923c7251f2SDavid Sterba test_err("cache free space is not 1Mb + %u", sectorsize); 59320005523SFilipe Manana return -EINVAL; 59420005523SFilipe Manana } 59520005523SFilipe Manana 59620005523SFilipe Manana offset = btrfs_find_space_for_alloc(cache, 597ee22184bSByongho Lee 0, SZ_1M, 0, 59820005523SFilipe Manana &max_extent_size); 599ee22184bSByongho Lee if (offset != (SZ_128M - SZ_256K)) { 6003c7251f2SDavid Sterba test_err( 6013c7251f2SDavid Sterba "failed to allocate 1Mb from space cache, returned offset is: %llu", 60220005523SFilipe Manana offset); 60320005523SFilipe Manana return -EINVAL; 60420005523SFilipe Manana } 60520005523SFilipe Manana 606b9ef22deSFeifei Xu /* 607b9ef22deSFeifei Xu * All that remains is a sectorsize free space region in a bitmap. 608b9ef22deSFeifei Xu * Confirm. 609b9ef22deSFeifei Xu */ 61020005523SFilipe Manana ret = check_num_extents_and_bitmaps(cache, 1, 1); 61120005523SFilipe Manana if (ret) 61220005523SFilipe Manana return ret; 61320005523SFilipe Manana 614b9ef22deSFeifei Xu if (cache->free_space_ctl->free_space != sectorsize) { 6153c7251f2SDavid Sterba test_err("cache free space is not %u", sectorsize); 61620005523SFilipe Manana return -EINVAL; 61720005523SFilipe Manana } 61820005523SFilipe Manana 61920005523SFilipe Manana offset = btrfs_find_space_for_alloc(cache, 620b9ef22deSFeifei Xu 0, sectorsize, 0, 62120005523SFilipe Manana &max_extent_size); 622ee22184bSByongho Lee if (offset != (SZ_128M + SZ_16M)) { 6233c7251f2SDavid Sterba test_err("failed to allocate %u, returned offset : %llu", 624b9ef22deSFeifei Xu sectorsize, offset); 62520005523SFilipe Manana return -EINVAL; 62620005523SFilipe Manana } 62720005523SFilipe Manana 62820005523SFilipe Manana ret = check_cache_empty(cache); 62920005523SFilipe Manana if (ret) 63020005523SFilipe Manana return ret; 63120005523SFilipe Manana 63220005523SFilipe Manana __btrfs_remove_free_space_cache(cache->free_space_ctl); 63320005523SFilipe Manana 63420005523SFilipe Manana /* 63520005523SFilipe Manana * Now test a similar scenario, but where our extent entry is located 63620005523SFilipe Manana * to the right of the bitmap entry, so that we can check that stealing 63720005523SFilipe Manana * space from a bitmap to the front of an extent entry works. 63820005523SFilipe Manana */ 63920005523SFilipe Manana 64020005523SFilipe Manana /* 64120005523SFilipe Manana * Extent entry covering free space range [128Mb + 128Kb, 128Mb + 256Kb[ 64220005523SFilipe Manana */ 643ee22184bSByongho Lee ret = test_add_free_space_entry(cache, SZ_128M + SZ_128K, SZ_128K, 0); 64420005523SFilipe Manana if (ret) { 6453c7251f2SDavid Sterba test_err("couldn't add extent entry %d", ret); 64620005523SFilipe Manana return ret; 64720005523SFilipe Manana } 64820005523SFilipe Manana 64920005523SFilipe Manana /* Bitmap entry covering free space range [0, 128Mb - 512Kb[ */ 650ee22184bSByongho Lee ret = test_add_free_space_entry(cache, 0, SZ_128M - SZ_512K, 1); 65120005523SFilipe Manana if (ret) { 6523c7251f2SDavid Sterba test_err("couldn't add bitmap entry %d", ret); 65320005523SFilipe Manana return ret; 65420005523SFilipe Manana } 65520005523SFilipe Manana 65620005523SFilipe Manana ret = check_num_extents_and_bitmaps(cache, 2, 1); 65720005523SFilipe Manana if (ret) 65820005523SFilipe Manana return ret; 65920005523SFilipe Manana 66020005523SFilipe Manana /* 66120005523SFilipe Manana * Now make only the last 256Kb of the bitmap marked as free, so that 66220005523SFilipe Manana * we end up with only the following ranges marked as free space: 66320005523SFilipe Manana * 66420005523SFilipe Manana * [128Mb + 128b, 128Mb + 256Kb[ 66520005523SFilipe Manana * [128Mb - 768Kb, 128Mb - 512Kb[ 66620005523SFilipe Manana */ 667ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, 0, SZ_128M - 768 * SZ_1K); 66820005523SFilipe Manana if (ret) { 6693c7251f2SDavid Sterba test_err("failed to free part of bitmap space %d", ret); 67020005523SFilipe Manana return ret; 67120005523SFilipe Manana } 67220005523SFilipe Manana 67320005523SFilipe Manana /* Confirm that only those 2 ranges are marked as free. */ 674ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M + SZ_128K, SZ_128K)) { 6753c7251f2SDavid Sterba test_err("free space range missing"); 67620005523SFilipe Manana return -ENOENT; 67720005523SFilipe Manana } 678ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M - 768 * SZ_1K, SZ_256K)) { 6793c7251f2SDavid Sterba test_err("free space range missing"); 68020005523SFilipe Manana return -ENOENT; 68120005523SFilipe Manana } 68220005523SFilipe Manana 68320005523SFilipe Manana /* 68420005523SFilipe Manana * Confirm that the bitmap range [0, 128Mb - 768Kb[ isn't marked 68520005523SFilipe Manana * as free anymore. 68620005523SFilipe Manana */ 687ee22184bSByongho Lee if (test_check_exists(cache, 0, SZ_128M - 768 * SZ_1K)) { 6883c7251f2SDavid Sterba test_err("bitmap region not removed from space cache"); 68920005523SFilipe Manana return -EINVAL; 69020005523SFilipe Manana } 69120005523SFilipe Manana 69220005523SFilipe Manana /* 69320005523SFilipe Manana * Confirm that the region [128Mb - 512Kb, 128Mb[, which is 69420005523SFilipe Manana * covered by the bitmap, isn't marked as free. 69520005523SFilipe Manana */ 696ee22184bSByongho Lee if (test_check_exists(cache, SZ_128M - SZ_512K, SZ_512K)) { 6973c7251f2SDavid Sterba test_err("invalid bitmap region marked as free"); 69820005523SFilipe Manana return -EINVAL; 69920005523SFilipe Manana } 70020005523SFilipe Manana 70120005523SFilipe Manana /* 70220005523SFilipe Manana * Now lets mark the region [128Mb - 512Kb, 128Mb[ as free too. But, 70320005523SFilipe Manana * lets make sure the free space cache marks it as free in the bitmap, 70420005523SFilipe Manana * and doesn't insert a new extent entry to represent this region. 70520005523SFilipe Manana */ 706ee22184bSByongho Lee ret = btrfs_add_free_space(cache, SZ_128M - SZ_512K, SZ_512K); 70720005523SFilipe Manana if (ret) { 7083c7251f2SDavid Sterba test_err("error adding free space: %d", ret); 70920005523SFilipe Manana return ret; 71020005523SFilipe Manana } 71120005523SFilipe Manana /* Confirm the region is marked as free. */ 712ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M - SZ_512K, SZ_512K)) { 7133c7251f2SDavid Sterba test_err("bitmap region not marked as free"); 71420005523SFilipe Manana return -ENOENT; 71520005523SFilipe Manana } 71620005523SFilipe Manana 71720005523SFilipe Manana /* 71820005523SFilipe Manana * Confirm that no new extent entries or bitmap entries were added to 71920005523SFilipe Manana * the cache after adding that free space region. 72020005523SFilipe Manana */ 72120005523SFilipe Manana ret = check_num_extents_and_bitmaps(cache, 2, 1); 72220005523SFilipe Manana if (ret) 72320005523SFilipe Manana return ret; 72420005523SFilipe Manana 72520005523SFilipe Manana /* 72620005523SFilipe Manana * Now lets add a small free space region to the left of the previous 72720005523SFilipe Manana * one, which is not contiguous with it and is part of the bitmap too. 72820005523SFilipe Manana * The goal is to test that the bitmap entry space stealing doesn't 72920005523SFilipe Manana * steal this space region. 73020005523SFilipe Manana */ 731b9ef22deSFeifei Xu ret = btrfs_add_free_space(cache, SZ_32M, 2 * sectorsize); 73220005523SFilipe Manana if (ret) { 7333c7251f2SDavid Sterba test_err("error adding free space: %d", ret); 73420005523SFilipe Manana return ret; 73520005523SFilipe Manana } 73620005523SFilipe Manana 73720005523SFilipe Manana /* 73820005523SFilipe Manana * Now mark the region [128Mb, 128Mb + 128Kb[ as free too. This will 73920005523SFilipe Manana * expand the range covered by the existing extent entry that represents 74020005523SFilipe Manana * the free space [128Mb + 128Kb, 128Mb + 256Kb[. 74120005523SFilipe Manana */ 742ee22184bSByongho Lee ret = btrfs_add_free_space(cache, SZ_128M, SZ_128K); 74320005523SFilipe Manana if (ret) { 7443c7251f2SDavid Sterba test_err("error adding free space: %d", ret); 74520005523SFilipe Manana return ret; 74620005523SFilipe Manana } 74720005523SFilipe Manana /* Confirm the region is marked as free. */ 748ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M, SZ_128K)) { 7493c7251f2SDavid Sterba test_err("extent region not marked as free"); 75020005523SFilipe Manana return -ENOENT; 75120005523SFilipe Manana } 75220005523SFilipe Manana 75320005523SFilipe Manana /* 75420005523SFilipe Manana * Confirm that our extent entry didn't stole all free space from the 755b9ef22deSFeifei Xu * bitmap, because of the small 2 * sectorsize free space region. 75620005523SFilipe Manana */ 75720005523SFilipe Manana ret = check_num_extents_and_bitmaps(cache, 2, 1); 75820005523SFilipe Manana if (ret) 75920005523SFilipe Manana return ret; 76020005523SFilipe Manana 76120005523SFilipe Manana /* 76220005523SFilipe Manana * So now we have the range [128Mb - 768Kb, 128Mb + 256Kb[ as free 76320005523SFilipe Manana * space. Without stealing bitmap free space into extent entry space, 76420005523SFilipe Manana * we would have all this free space represented by 2 entries in the 76520005523SFilipe Manana * cache: 76620005523SFilipe Manana * 76720005523SFilipe Manana * extent entry covering range: [128Mb, 128Mb + 256Kb[ 76820005523SFilipe Manana * bitmap entry covering range: [128Mb - 768Kb, 128Mb[ 76920005523SFilipe Manana * 77020005523SFilipe Manana * Attempting to allocate the whole free space (1Mb) would fail, because 77120005523SFilipe Manana * we can't allocate from multiple entries. 77220005523SFilipe Manana * With the bitmap free space stealing, we get a single extent entry 77320005523SFilipe Manana * that represents the 1Mb free space, and therefore we're able to 77420005523SFilipe Manana * allocate the whole free space at once. 77520005523SFilipe Manana */ 776ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M - 768 * SZ_1K, SZ_1M)) { 7773c7251f2SDavid Sterba test_err("expected region not marked as free"); 77820005523SFilipe Manana return -ENOENT; 77920005523SFilipe Manana } 78020005523SFilipe Manana 781b9ef22deSFeifei Xu if (cache->free_space_ctl->free_space != (SZ_1M + 2 * sectorsize)) { 7823c7251f2SDavid Sterba test_err("cache free space is not 1Mb + %u", 2 * sectorsize); 78320005523SFilipe Manana return -EINVAL; 78420005523SFilipe Manana } 78520005523SFilipe Manana 786ee22184bSByongho Lee offset = btrfs_find_space_for_alloc(cache, 0, SZ_1M, 0, 78720005523SFilipe Manana &max_extent_size); 788ee22184bSByongho Lee if (offset != (SZ_128M - 768 * SZ_1K)) { 7893c7251f2SDavid Sterba test_err( 7903c7251f2SDavid Sterba "failed to allocate 1Mb from space cache, returned offset is: %llu", 79120005523SFilipe Manana offset); 79220005523SFilipe Manana return -EINVAL; 79320005523SFilipe Manana } 79420005523SFilipe Manana 795b9ef22deSFeifei Xu /* 796b9ef22deSFeifei Xu * All that remains is 2 * sectorsize free space region 797b9ef22deSFeifei Xu * in a bitmap. Confirm. 798b9ef22deSFeifei Xu */ 79920005523SFilipe Manana ret = check_num_extents_and_bitmaps(cache, 1, 1); 80020005523SFilipe Manana if (ret) 80120005523SFilipe Manana return ret; 80220005523SFilipe Manana 803b9ef22deSFeifei Xu if (cache->free_space_ctl->free_space != 2 * sectorsize) { 8043c7251f2SDavid Sterba test_err("cache free space is not %u", 2 * sectorsize); 80520005523SFilipe Manana return -EINVAL; 80620005523SFilipe Manana } 80720005523SFilipe Manana 80820005523SFilipe Manana offset = btrfs_find_space_for_alloc(cache, 809b9ef22deSFeifei Xu 0, 2 * sectorsize, 0, 81020005523SFilipe Manana &max_extent_size); 811ee22184bSByongho Lee if (offset != SZ_32M) { 8123c7251f2SDavid Sterba test_err("failed to allocate %u, offset: %llu", 8133c7251f2SDavid Sterba 2 * sectorsize, offset); 81420005523SFilipe Manana return -EINVAL; 81520005523SFilipe Manana } 81620005523SFilipe Manana 81720005523SFilipe Manana ret = check_cache_empty(cache); 81820005523SFilipe Manana if (ret) 81920005523SFilipe Manana return ret; 82020005523SFilipe Manana 82128f0779aSDavid Sterba cache->free_space_ctl->op = orig_free_space_ops; 82220005523SFilipe Manana __btrfs_remove_free_space_cache(cache->free_space_ctl); 82320005523SFilipe Manana 82420005523SFilipe Manana return 0; 82520005523SFilipe Manana } 82620005523SFilipe Manana 827*bbf27275SJosef Bacik static bool bytes_index_use_bitmap(struct btrfs_free_space_ctl *ctl, 828*bbf27275SJosef Bacik struct btrfs_free_space *info) 829*bbf27275SJosef Bacik { 830*bbf27275SJosef Bacik return true; 831*bbf27275SJosef Bacik } 832*bbf27275SJosef Bacik 833*bbf27275SJosef Bacik static int test_bytes_index(struct btrfs_block_group *cache, u32 sectorsize) 834*bbf27275SJosef Bacik { 835*bbf27275SJosef Bacik const struct btrfs_free_space_op test_free_space_ops = { 836*bbf27275SJosef Bacik .use_bitmap = bytes_index_use_bitmap, 837*bbf27275SJosef Bacik }; 838*bbf27275SJosef Bacik const struct btrfs_free_space_op *orig_free_space_ops; 839*bbf27275SJosef Bacik struct btrfs_free_space_ctl *ctl = cache->free_space_ctl; 840*bbf27275SJosef Bacik struct btrfs_free_space *entry; 841*bbf27275SJosef Bacik struct rb_node *node; 842*bbf27275SJosef Bacik u64 offset, max_extent_size, bytes; 843*bbf27275SJosef Bacik int ret, i; 844*bbf27275SJosef Bacik 845*bbf27275SJosef Bacik test_msg("running bytes index tests"); 846*bbf27275SJosef Bacik 847*bbf27275SJosef Bacik /* First just validate that it does everything in order. */ 848*bbf27275SJosef Bacik offset = 0; 849*bbf27275SJosef Bacik for (i = 0; i < 10; i++) { 850*bbf27275SJosef Bacik bytes = (i + 1) * SZ_1M; 851*bbf27275SJosef Bacik ret = test_add_free_space_entry(cache, offset, bytes, 0); 852*bbf27275SJosef Bacik if (ret) { 853*bbf27275SJosef Bacik test_err("couldn't add extent entry %d\n", ret); 854*bbf27275SJosef Bacik return ret; 855*bbf27275SJosef Bacik } 856*bbf27275SJosef Bacik offset += bytes + sectorsize; 857*bbf27275SJosef Bacik } 858*bbf27275SJosef Bacik 859*bbf27275SJosef Bacik for (node = rb_first_cached(&ctl->free_space_bytes), i = 9; node; 860*bbf27275SJosef Bacik node = rb_next(node), i--) { 861*bbf27275SJosef Bacik entry = rb_entry(node, struct btrfs_free_space, bytes_index); 862*bbf27275SJosef Bacik bytes = (i + 1) * SZ_1M; 863*bbf27275SJosef Bacik if (entry->bytes != bytes) { 864*bbf27275SJosef Bacik test_err("invalid bytes index order, found %llu expected %llu", 865*bbf27275SJosef Bacik entry->bytes, bytes); 866*bbf27275SJosef Bacik return -EINVAL; 867*bbf27275SJosef Bacik } 868*bbf27275SJosef Bacik } 869*bbf27275SJosef Bacik 870*bbf27275SJosef Bacik /* Now validate bitmaps do the correct thing. */ 871*bbf27275SJosef Bacik __btrfs_remove_free_space_cache(cache->free_space_ctl); 872*bbf27275SJosef Bacik for (i = 0; i < 2; i++) { 873*bbf27275SJosef Bacik offset = i * BITS_PER_BITMAP * sectorsize; 874*bbf27275SJosef Bacik bytes = (i + 1) * SZ_1M; 875*bbf27275SJosef Bacik ret = test_add_free_space_entry(cache, offset, bytes, 1); 876*bbf27275SJosef Bacik if (ret) { 877*bbf27275SJosef Bacik test_err("couldn't add bitmap entry"); 878*bbf27275SJosef Bacik return ret; 879*bbf27275SJosef Bacik } 880*bbf27275SJosef Bacik } 881*bbf27275SJosef Bacik 882*bbf27275SJosef Bacik for (node = rb_first_cached(&ctl->free_space_bytes), i = 1; node; 883*bbf27275SJosef Bacik node = rb_next(node), i--) { 884*bbf27275SJosef Bacik entry = rb_entry(node, struct btrfs_free_space, bytes_index); 885*bbf27275SJosef Bacik bytes = (i + 1) * SZ_1M; 886*bbf27275SJosef Bacik if (entry->bytes != bytes) { 887*bbf27275SJosef Bacik test_err("invalid bytes index order, found %llu expected %llu", 888*bbf27275SJosef Bacik entry->bytes, bytes); 889*bbf27275SJosef Bacik return -EINVAL; 890*bbf27275SJosef Bacik } 891*bbf27275SJosef Bacik } 892*bbf27275SJosef Bacik 893*bbf27275SJosef Bacik /* Now validate bitmaps with different ->max_extent_size. */ 894*bbf27275SJosef Bacik __btrfs_remove_free_space_cache(cache->free_space_ctl); 895*bbf27275SJosef Bacik orig_free_space_ops = cache->free_space_ctl->op; 896*bbf27275SJosef Bacik cache->free_space_ctl->op = &test_free_space_ops; 897*bbf27275SJosef Bacik 898*bbf27275SJosef Bacik ret = test_add_free_space_entry(cache, 0, sectorsize, 1); 899*bbf27275SJosef Bacik if (ret) { 900*bbf27275SJosef Bacik test_err("couldn't add bitmap entry"); 901*bbf27275SJosef Bacik return ret; 902*bbf27275SJosef Bacik } 903*bbf27275SJosef Bacik 904*bbf27275SJosef Bacik offset = BITS_PER_BITMAP * sectorsize; 905*bbf27275SJosef Bacik ret = test_add_free_space_entry(cache, offset, sectorsize, 1); 906*bbf27275SJosef Bacik if (ret) { 907*bbf27275SJosef Bacik test_err("couldn't add bitmap_entry"); 908*bbf27275SJosef Bacik return ret; 909*bbf27275SJosef Bacik } 910*bbf27275SJosef Bacik 911*bbf27275SJosef Bacik /* 912*bbf27275SJosef Bacik * Now set a bunch of sectorsize extents in the first entry so it's 913*bbf27275SJosef Bacik * ->bytes is large. 914*bbf27275SJosef Bacik */ 915*bbf27275SJosef Bacik for (i = 2; i < 20; i += 2) { 916*bbf27275SJosef Bacik offset = sectorsize * i; 917*bbf27275SJosef Bacik ret = btrfs_add_free_space(cache, offset, sectorsize); 918*bbf27275SJosef Bacik if (ret) { 919*bbf27275SJosef Bacik test_err("error populating sparse bitmap %d", ret); 920*bbf27275SJosef Bacik return ret; 921*bbf27275SJosef Bacik } 922*bbf27275SJosef Bacik } 923*bbf27275SJosef Bacik 924*bbf27275SJosef Bacik /* 925*bbf27275SJosef Bacik * Now set a contiguous extent in the second bitmap so its 926*bbf27275SJosef Bacik * ->max_extent_size is larger than the first bitmaps. 927*bbf27275SJosef Bacik */ 928*bbf27275SJosef Bacik offset = (BITS_PER_BITMAP * sectorsize) + sectorsize; 929*bbf27275SJosef Bacik ret = btrfs_add_free_space(cache, offset, sectorsize); 930*bbf27275SJosef Bacik if (ret) { 931*bbf27275SJosef Bacik test_err("error adding contiguous extent %d", ret); 932*bbf27275SJosef Bacik return ret; 933*bbf27275SJosef Bacik } 934*bbf27275SJosef Bacik 935*bbf27275SJosef Bacik /* 936*bbf27275SJosef Bacik * Since we don't set ->max_extent_size unless we search everything 937*bbf27275SJosef Bacik * should be indexed on bytes. 938*bbf27275SJosef Bacik */ 939*bbf27275SJosef Bacik entry = rb_entry(rb_first_cached(&ctl->free_space_bytes), 940*bbf27275SJosef Bacik struct btrfs_free_space, bytes_index); 941*bbf27275SJosef Bacik if (entry->bytes != (10 * sectorsize)) { 942*bbf27275SJosef Bacik test_err("error, wrong entry in the first slot in bytes_index"); 943*bbf27275SJosef Bacik return -EINVAL; 944*bbf27275SJosef Bacik } 945*bbf27275SJosef Bacik 946*bbf27275SJosef Bacik max_extent_size = 0; 947*bbf27275SJosef Bacik offset = btrfs_find_space_for_alloc(cache, cache->start, sectorsize * 3, 948*bbf27275SJosef Bacik 0, &max_extent_size); 949*bbf27275SJosef Bacik if (offset != 0) { 950*bbf27275SJosef Bacik test_err("found space to alloc even though we don't have enough space"); 951*bbf27275SJosef Bacik return -EINVAL; 952*bbf27275SJosef Bacik } 953*bbf27275SJosef Bacik 954*bbf27275SJosef Bacik if (max_extent_size != (2 * sectorsize)) { 955*bbf27275SJosef Bacik test_err("got the wrong max_extent size %llu expected %llu", 956*bbf27275SJosef Bacik max_extent_size, (unsigned long long)(2 * sectorsize)); 957*bbf27275SJosef Bacik return -EINVAL; 958*bbf27275SJosef Bacik } 959*bbf27275SJosef Bacik 960*bbf27275SJosef Bacik /* 961*bbf27275SJosef Bacik * The search should have re-arranged the bytes index to use the 962*bbf27275SJosef Bacik * ->max_extent_size, validate it's now what we expect it to be. 963*bbf27275SJosef Bacik */ 964*bbf27275SJosef Bacik entry = rb_entry(rb_first_cached(&ctl->free_space_bytes), 965*bbf27275SJosef Bacik struct btrfs_free_space, bytes_index); 966*bbf27275SJosef Bacik if (entry->bytes != (2 * sectorsize)) { 967*bbf27275SJosef Bacik test_err("error, the bytes index wasn't recalculated properly"); 968*bbf27275SJosef Bacik return -EINVAL; 969*bbf27275SJosef Bacik } 970*bbf27275SJosef Bacik 971*bbf27275SJosef Bacik /* Add another sectorsize to re-arrange the tree back to ->bytes. */ 972*bbf27275SJosef Bacik offset = (BITS_PER_BITMAP * sectorsize) - sectorsize; 973*bbf27275SJosef Bacik ret = btrfs_add_free_space(cache, offset, sectorsize); 974*bbf27275SJosef Bacik if (ret) { 975*bbf27275SJosef Bacik test_err("error adding extent to the sparse entry %d", ret); 976*bbf27275SJosef Bacik return ret; 977*bbf27275SJosef Bacik } 978*bbf27275SJosef Bacik 979*bbf27275SJosef Bacik entry = rb_entry(rb_first_cached(&ctl->free_space_bytes), 980*bbf27275SJosef Bacik struct btrfs_free_space, bytes_index); 981*bbf27275SJosef Bacik if (entry->bytes != (11 * sectorsize)) { 982*bbf27275SJosef Bacik test_err("error, wrong entry in the first slot in bytes_index"); 983*bbf27275SJosef Bacik return -EINVAL; 984*bbf27275SJosef Bacik } 985*bbf27275SJosef Bacik 986*bbf27275SJosef Bacik /* 987*bbf27275SJosef Bacik * Now make sure we find our correct entry after searching that will 988*bbf27275SJosef Bacik * result in a re-arranging of the tree. 989*bbf27275SJosef Bacik */ 990*bbf27275SJosef Bacik max_extent_size = 0; 991*bbf27275SJosef Bacik offset = btrfs_find_space_for_alloc(cache, cache->start, sectorsize * 2, 992*bbf27275SJosef Bacik 0, &max_extent_size); 993*bbf27275SJosef Bacik if (offset != (BITS_PER_BITMAP * sectorsize)) { 994*bbf27275SJosef Bacik test_err("error, found %llu instead of %llu for our alloc", 995*bbf27275SJosef Bacik offset, 996*bbf27275SJosef Bacik (unsigned long long)(BITS_PER_BITMAP * sectorsize)); 997*bbf27275SJosef Bacik return -EINVAL; 998*bbf27275SJosef Bacik } 999*bbf27275SJosef Bacik 1000*bbf27275SJosef Bacik cache->free_space_ctl->op = orig_free_space_ops; 1001*bbf27275SJosef Bacik __btrfs_remove_free_space_cache(cache->free_space_ctl); 1002*bbf27275SJosef Bacik return 0; 1003*bbf27275SJosef Bacik } 1004*bbf27275SJosef Bacik 1005b9ef22deSFeifei Xu int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize) 1006dc11dd5dSJosef Bacik { 10077c0260eeSJeff Mahoney struct btrfs_fs_info *fs_info; 100832da5386SDavid Sterba struct btrfs_block_group *cache; 1009d0bd4560SJosef Bacik struct btrfs_root *root = NULL; 1010d0bd4560SJosef Bacik int ret = -ENOMEM; 1011dc11dd5dSJosef Bacik 1012315b76b4SDavid Sterba test_msg("running btrfs free space cache tests"); 1013da17066cSJeff Mahoney fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize); 101437b2a7bcSDavid Sterba if (!fs_info) { 101537b2a7bcSDavid Sterba test_std_err(TEST_ALLOC_FS_INFO); 1016da17066cSJeff Mahoney return -ENOMEM; 101737b2a7bcSDavid Sterba } 1018dc11dd5dSJosef Bacik 101936b3dc05SFeifei Xu /* 102036b3dc05SFeifei Xu * For ppc64 (with 64k page size), bytes per bitmap might be 102136b3dc05SFeifei Xu * larger than 1G. To make bitmap test available in ppc64, 102236b3dc05SFeifei Xu * alloc dummy block group whose size cross bitmaps. 102336b3dc05SFeifei Xu */ 1024da17066cSJeff Mahoney cache = btrfs_alloc_dummy_block_group(fs_info, 1025da17066cSJeff Mahoney BITS_PER_BITMAP * sectorsize + PAGE_SIZE); 1026dc11dd5dSJosef Bacik if (!cache) { 10273199366dSDavid Sterba test_std_err(TEST_ALLOC_BLOCK_GROUP); 1028da17066cSJeff Mahoney btrfs_free_dummy_fs_info(fs_info); 1029dc11dd5dSJosef Bacik return 0; 1030dc11dd5dSJosef Bacik } 1031dc11dd5dSJosef Bacik 1032da17066cSJeff Mahoney root = btrfs_alloc_dummy_root(fs_info); 103389b6c8d1SDan Carpenter if (IS_ERR(root)) { 103452ab7bcaSDavid Sterba test_std_err(TEST_ALLOC_ROOT); 103589b6c8d1SDan Carpenter ret = PTR_ERR(root); 1036d0bd4560SJosef Bacik goto out; 103789b6c8d1SDan Carpenter } 1038d0bd4560SJosef Bacik 1039d0bd4560SJosef Bacik root->fs_info->extent_root = root; 1040d0bd4560SJosef Bacik 1041dc11dd5dSJosef Bacik ret = test_extents(cache); 1042dc11dd5dSJosef Bacik if (ret) 1043dc11dd5dSJosef Bacik goto out; 1044b9ef22deSFeifei Xu ret = test_bitmaps(cache, sectorsize); 1045dc11dd5dSJosef Bacik if (ret) 1046dc11dd5dSJosef Bacik goto out; 1047b9ef22deSFeifei Xu ret = test_bitmaps_and_extents(cache, sectorsize); 1048dc11dd5dSJosef Bacik if (ret) 1049dc11dd5dSJosef Bacik goto out; 105020005523SFilipe Manana 1051b9ef22deSFeifei Xu ret = test_steal_space_from_bitmap_to_extent(cache, sectorsize); 1052*bbf27275SJosef Bacik if (ret) 1053*bbf27275SJosef Bacik goto out; 1054*bbf27275SJosef Bacik ret = test_bytes_index(cache, sectorsize); 1055dc11dd5dSJosef Bacik out: 10567c55ee0cSOmar Sandoval btrfs_free_dummy_block_group(cache); 1057d0bd4560SJosef Bacik btrfs_free_dummy_root(root); 10587c0260eeSJeff Mahoney btrfs_free_dummy_fs_info(fs_info); 1059dc11dd5dSJosef Bacik return ret; 1060dc11dd5dSJosef Bacik } 1061