aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2013-03-15 09:47:08 -0400
committerJosef Bacik <jbacik@fusionio.com>2013-05-06 15:52:54 -0400
commit74255aa07d292385ca3a4a4e8f0bc492d9bdd116 (patch)
tree02ee09448bbb988baf59bed8615a9f0dcc608a5a
parente75206cfdc89f4b5361776443acba4c940770b30 (diff)
Btrfs: add some free space cache tests
We keep hitting bugs in the tree log replay because btrfs_remove_free_space doesn't account for some corner case. So add a bunch of tests to try and fully test btrfs_remove_free_space since the only time it is called is during tree log replay. These tests all finish successfully, so as we find more of these bugs we need to add to these tests to make sure we don't regress in fixing things. I've hidden the tests behind a Kconfig option, but they take no time to run so all btrfs developers should have this turned on all the time. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com>
-rw-r--r--fs/btrfs/Kconfig11
-rw-r--r--fs/btrfs/free-space-cache.c519
-rw-r--r--fs/btrfs/free-space-cache.h5
-rw-r--r--fs/btrfs/super.c5
4 files changed, 540 insertions, 0 deletions
diff --git a/fs/btrfs/Kconfig b/fs/btrfs/Kconfig
index 9a8622a5b867..d5bfcb744fe5 100644
--- a/fs/btrfs/Kconfig
+++ b/fs/btrfs/Kconfig
@@ -52,3 +52,14 @@ config BTRFS_FS_CHECK_INTEGRITY
52 In most cases, unless you are a btrfs developer who needs 52 In most cases, unless you are a btrfs developer who needs
53 to verify the integrity of (super)-block write requests 53 to verify the integrity of (super)-block write requests
54 during the run of a regression test, say N 54 during the run of a regression test, say N
55
56config BTRFS_FS_RUN_SANITY_TESTS
57 bool "Btrfs will run sanity tests upon loading"
58 depends on BTRFS_FS
59 help
60 This will run some basic sanity tests on the free space cache
61 code to make sure it is acting as it should. These are mostly
62 regression tests and are only really interesting to btrfs devlopers.
63
64 If unsure, say N.
65
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index 1f84fc09c1a8..1d80afa6d3db 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -2967,3 +2967,522 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root,
2967 iput(inode); 2967 iput(inode);
2968 return ret; 2968 return ret;
2969} 2969}
2970
2971#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
2972static struct btrfs_block_group_cache *init_test_block_group(void)
2973{
2974 struct btrfs_block_group_cache *cache;
2975
2976 cache = kzalloc(sizeof(*cache), GFP_NOFS);
2977 if (!cache)
2978 return NULL;
2979 cache->free_space_ctl = kzalloc(sizeof(*cache->free_space_ctl),
2980 GFP_NOFS);
2981 if (!cache->free_space_ctl) {
2982 kfree(cache);
2983 return NULL;
2984 }
2985
2986 cache->key.objectid = 0;
2987 cache->key.offset = 1024 * 1024 * 1024;
2988 cache->key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
2989 cache->sectorsize = 4096;
2990
2991 spin_lock_init(&cache->lock);
2992 INIT_LIST_HEAD(&cache->list);
2993 INIT_LIST_HEAD(&cache->cluster_list);
2994 INIT_LIST_HEAD(&cache->new_bg_list);
2995
2996 btrfs_init_free_space_ctl(cache);
2997
2998 return cache;
2999}
3000
3001/*
3002 * Checks to see if the given range is in the free space cache. This is really
3003 * just used to check the absence of space, so if there is free space in the
3004 * range at all we will return 1.
3005 */
3006static int check_exists(struct btrfs_block_group_cache *cache, u64 offset,
3007 u64 bytes)
3008{
3009 struct btrfs_free_space_ctl *ctl = cache->free_space_ctl;
3010 struct btrfs_free_space *info;
3011 int ret = 0;
3012
3013 spin_lock(&ctl->tree_lock);
3014 info = tree_search_offset(ctl, offset, 0, 0);
3015 if (!info) {
3016 info = tree_search_offset(ctl, offset_to_bitmap(ctl, offset),
3017 1, 0);
3018 if (!info)
3019 goto out;
3020 }
3021
3022have_info:
3023 if (info->bitmap) {
3024 u64 bit_off, bit_bytes;
3025 struct rb_node *n;
3026 struct btrfs_free_space *tmp;
3027
3028 bit_off = offset;
3029 bit_bytes = ctl->unit;
3030 ret = search_bitmap(ctl, info, &bit_off, &bit_bytes);
3031 if (!ret) {
3032 if (bit_off == offset) {
3033 ret = 1;
3034 goto out;
3035 } else if (bit_off > offset &&
3036 offset + bytes > bit_off) {
3037 ret = 1;
3038 goto out;
3039 }
3040 }
3041
3042 n = rb_prev(&info->offset_index);
3043 while (n) {
3044 tmp = rb_entry(n, struct btrfs_free_space,
3045 offset_index);
3046 if (tmp->offset + tmp->bytes < offset)
3047 break;
3048 if (offset + bytes < tmp->offset) {
3049 n = rb_prev(&info->offset_index);
3050 continue;
3051 }
3052 info = tmp;
3053 goto have_info;
3054 }
3055
3056 n = rb_next(&info->offset_index);
3057 while (n) {
3058 tmp = rb_entry(n, struct btrfs_free_space,
3059 offset_index);
3060 if (offset + bytes < tmp->offset)
3061 break;
3062 if (tmp->offset + tmp->bytes < offset) {
3063 n = rb_next(&info->offset_index);
3064 continue;
3065 }
3066 info = tmp;
3067 goto have_info;
3068 }
3069
3070 goto out;
3071 }
3072
3073 if (info->offset == offset) {
3074 ret = 1;
3075 goto out;
3076 }
3077
3078 if (offset > info->offset && offset < info->offset + info->bytes)
3079 ret = 1;
3080out:
3081 spin_unlock(&ctl->tree_lock);
3082 return ret;
3083}
3084
3085/*
3086 * Use this if you need to make a bitmap or extent entry specifically, it
3087 * doesn't do any of the merging that add_free_space does, this acts a lot like
3088 * how the free space cache loading stuff works, so you can get really weird
3089 * configurations.
3090 */
3091static int add_free_space_entry(struct btrfs_block_group_cache *cache,
3092 u64 offset, u64 bytes, bool bitmap)
3093{
3094 struct btrfs_free_space_ctl *ctl = cache->free_space_ctl;
3095 struct btrfs_free_space *info = NULL, *bitmap_info;
3096 void *map = NULL;
3097 u64 bytes_added;
3098 int ret;
3099
3100again:
3101 if (!info) {
3102 info = kmem_cache_zalloc(btrfs_free_space_cachep, GFP_NOFS);
3103 if (!info)
3104 return -ENOMEM;
3105 }
3106
3107 if (!bitmap) {
3108 spin_lock(&ctl->tree_lock);
3109 info->offset = offset;
3110 info->bytes = bytes;
3111 ret = link_free_space(ctl, info);
3112 spin_unlock(&ctl->tree_lock);
3113 if (ret)
3114 kmem_cache_free(btrfs_free_space_cachep, info);
3115 return ret;
3116 }
3117
3118 if (!map) {
3119 map = kzalloc(PAGE_CACHE_SIZE, GFP_NOFS);
3120 if (!map) {
3121 kmem_cache_free(btrfs_free_space_cachep, info);
3122 return -ENOMEM;
3123 }
3124 }
3125
3126 spin_lock(&ctl->tree_lock);
3127 bitmap_info = tree_search_offset(ctl, offset_to_bitmap(ctl, offset),
3128 1, 0);
3129 if (!bitmap_info) {
3130 info->bitmap = map;
3131 map = NULL;
3132 add_new_bitmap(ctl, info, offset);
3133 bitmap_info = info;
3134 }
3135
3136 bytes_added = add_bytes_to_bitmap(ctl, bitmap_info, offset, bytes);
3137 bytes -= bytes_added;
3138 offset += bytes_added;
3139 spin_unlock(&ctl->tree_lock);
3140
3141 if (bytes)
3142 goto again;
3143
3144 if (map)
3145 kfree(map);
3146 return 0;
3147}
3148
3149/*
3150 * This test just does basic sanity checking, making sure we can add an exten
3151 * entry and remove space from either end and the middle, and make sure we can
3152 * remove space that covers adjacent extent entries.
3153 */
3154static int test_extents(struct btrfs_block_group_cache *cache)
3155{
3156 int ret = 0;
3157
3158 printk(KERN_ERR "Running extent only tests\n");
3159
3160 /* First just make sure we can remove an entire entry */
3161 ret = btrfs_add_free_space(cache, 0, 4 * 1024 * 1024);
3162 if (ret) {
3163 printk(KERN_ERR "Error adding initial extents %d\n", ret);
3164 return ret;
3165 }
3166
3167 ret = btrfs_remove_free_space(cache, 0, 4 * 1024 * 1024);
3168 if (ret) {
3169 printk(KERN_ERR "Error removing extent %d\n", ret);
3170 return ret;
3171 }
3172
3173 if (check_exists(cache, 0, 4 * 1024 * 1024)) {
3174 printk(KERN_ERR "Full remove left some lingering space\n");
3175 return -1;
3176 }
3177
3178 /* Ok edge and middle cases now */
3179 ret = btrfs_add_free_space(cache, 0, 4 * 1024 * 1024);
3180 if (ret) {
3181 printk(KERN_ERR "Error adding half extent %d\n", ret);
3182 return ret;
3183 }
3184
3185 ret = btrfs_remove_free_space(cache, 3 * 1024 * 1024, 1 * 1024 * 1024);
3186 if (ret) {
3187 printk(KERN_ERR "Error removing tail end %d\n", ret);
3188 return ret;
3189 }
3190
3191 ret = btrfs_remove_free_space(cache, 0, 1 * 1024 * 1024);
3192 if (ret) {
3193 printk(KERN_ERR "Error removing front end %d\n", ret);
3194 return ret;
3195 }
3196
3197 ret = btrfs_remove_free_space(cache, 2 * 1024 * 1024, 4096);
3198 if (ret) {
3199 printk(KERN_ERR "Error removing middle peice %d\n", ret);
3200 return ret;
3201 }
3202
3203 if (check_exists(cache, 0, 1 * 1024 * 1024)) {
3204 printk(KERN_ERR "Still have space at the front\n");
3205 return -1;
3206 }
3207
3208 if (check_exists(cache, 2 * 1024 * 1024, 4096)) {
3209 printk(KERN_ERR "Still have space in the middle\n");
3210 return -1;
3211 }
3212
3213 if (check_exists(cache, 3 * 1024 * 1024, 1 * 1024 * 1024)) {
3214 printk(KERN_ERR "Still have space at the end\n");
3215 return -1;
3216 }
3217
3218 /* Cleanup */
3219 __btrfs_remove_free_space_cache(cache->free_space_ctl);
3220
3221 return 0;
3222}
3223
3224static int test_bitmaps(struct btrfs_block_group_cache *cache)
3225{
3226 u64 next_bitmap_offset;
3227 int ret;
3228
3229 printk(KERN_ERR "Running bitmap only tests\n");
3230
3231 ret = add_free_space_entry(cache, 0, 4 * 1024 * 1024, 1);
3232 if (ret) {
3233 printk(KERN_ERR "Couldn't create a bitmap entry %d\n", ret);
3234 return ret;
3235 }
3236
3237 ret = btrfs_remove_free_space(cache, 0, 4 * 1024 * 1024);
3238 if (ret) {
3239 printk(KERN_ERR "Error removing bitmap full range %d\n", ret);
3240 return ret;
3241 }
3242
3243 if (check_exists(cache, 0, 4 * 1024 * 1024)) {
3244 printk(KERN_ERR "Left some space in bitmap\n");
3245 return -1;
3246 }
3247
3248 ret = add_free_space_entry(cache, 0, 4 * 1024 * 1024, 1);
3249 if (ret) {
3250 printk(KERN_ERR "Couldn't add to our bitmap entry %d\n", ret);
3251 return ret;
3252 }
3253
3254 ret = btrfs_remove_free_space(cache, 1 * 1024 * 1024, 2 * 1024 * 1024);
3255 if (ret) {
3256 printk(KERN_ERR "Couldn't remove middle chunk %d\n", ret);
3257 return ret;
3258 }
3259
3260 /*
3261 * The first bitmap we have starts at offset 0 so the next one is just
3262 * at the end of the first bitmap.
3263 */
3264 next_bitmap_offset = (u64)(BITS_PER_BITMAP * 4096);
3265
3266 /* Test a bit straddling two bitmaps */
3267 ret = add_free_space_entry(cache, next_bitmap_offset -
3268 (2 * 1024 * 1024), 4 * 1024 * 1024, 1);
3269 if (ret) {
3270 printk(KERN_ERR "Couldn't add space that straddles two bitmaps"
3271 " %d\n", ret);
3272 return ret;
3273 }
3274
3275 ret = btrfs_remove_free_space(cache, next_bitmap_offset -
3276 (1 * 1024 * 1024), 2 * 1024 * 1024);
3277 if (ret) {
3278 printk(KERN_ERR "Couldn't remove overlapping space %d\n", ret);
3279 return ret;
3280 }
3281
3282 if (check_exists(cache, next_bitmap_offset - (1 * 1024 * 1024),
3283 2 * 1024 * 1024)) {
3284 printk(KERN_ERR "Left some space when removing overlapping\n");
3285 return -1;
3286 }
3287
3288 __btrfs_remove_free_space_cache(cache->free_space_ctl);
3289
3290 return 0;
3291}
3292
3293/* This is the high grade jackassery */
3294static int test_bitmaps_and_extents(struct btrfs_block_group_cache *cache)
3295{
3296 u64 bitmap_offset = (u64)(BITS_PER_BITMAP * 4096);
3297 int ret;
3298
3299 printk(KERN_ERR "Running bitmap and extent tests\n");
3300
3301 /*
3302 * First let's do something simple, an extent at the same offset as the
3303 * bitmap, but the free space completely in the extent and then
3304 * completely in the bitmap.
3305 */
3306 ret = add_free_space_entry(cache, 4 * 1024 * 1024, 1 * 1024 * 1024, 1);
3307 if (ret) {
3308 printk(KERN_ERR "Couldn't create bitmap entry %d\n", ret);
3309 return ret;
3310 }
3311
3312 ret = add_free_space_entry(cache, 0, 1 * 1024 * 1024, 0);
3313 if (ret) {
3314 printk(KERN_ERR "Couldn't add extent entry %d\n", ret);
3315 return ret;
3316 }
3317
3318 ret = btrfs_remove_free_space(cache, 0, 1 * 1024 * 1024);
3319 if (ret) {
3320 printk(KERN_ERR "Couldn't remove extent entry %d\n", ret);
3321 return ret;
3322 }
3323
3324 if (check_exists(cache, 0, 1 * 1024 * 1024)) {
3325 printk(KERN_ERR "Left remnants after our remove\n");
3326 return -1;
3327 }
3328
3329 /* Now to add back the extent entry and remove from the bitmap */
3330 ret = add_free_space_entry(cache, 0, 1 * 1024 * 1024, 0);
3331 if (ret) {
3332 printk(KERN_ERR "Couldn't re-add extent entry %d\n", ret);
3333 return ret;
3334 }
3335
3336 ret = btrfs_remove_free_space(cache, 4 * 1024 * 1024, 1 * 1024 * 1024);
3337 if (ret) {
3338 printk(KERN_ERR "Couldn't remove from bitmap %d\n", ret);
3339 return ret;
3340 }
3341
3342 if (check_exists(cache, 4 * 1024 * 1024, 1 * 1024 * 1024)) {
3343 printk(KERN_ERR "Left remnants in the bitmap\n");
3344 return -1;
3345 }
3346
3347 /*
3348 * Ok so a little more evil, extent entry and bitmap at the same offset,
3349 * removing an overlapping chunk.
3350 */
3351 ret = add_free_space_entry(cache, 1 * 1024 * 1024, 4 * 1024 * 1024, 1);
3352 if (ret) {
3353 printk(KERN_ERR "Couldn't add to a bitmap %d\n", ret);
3354 return ret;
3355 }
3356
3357 ret = btrfs_remove_free_space(cache, 512 * 1024, 3 * 1024 * 1024);
3358 if (ret) {
3359 printk(KERN_ERR "Couldn't remove overlapping space %d\n", ret);
3360 return ret;
3361 }
3362
3363 if (check_exists(cache, 512 * 1024, 3 * 1024 * 1024)) {
3364 printk(KERN_ERR "Left over peices after removing "
3365 "overlapping\n");
3366 return -1;
3367 }
3368
3369 __btrfs_remove_free_space_cache(cache->free_space_ctl);
3370
3371 /* Now with the extent entry offset into the bitmap */
3372 ret = add_free_space_entry(cache, 4 * 1024 * 1024, 4 * 1024 * 1024, 1);
3373 if (ret) {
3374 printk(KERN_ERR "Couldn't add space to the bitmap %d\n", ret);
3375 return ret;
3376 }
3377
3378 ret = add_free_space_entry(cache, 2 * 1024 * 1024, 2 * 1024 * 1024, 0);
3379 if (ret) {
3380 printk(KERN_ERR "Couldn't add extent to the cache %d\n", ret);
3381 return ret;
3382 }
3383
3384 ret = btrfs_remove_free_space(cache, 3 * 1024 * 1024, 4 * 1024 * 1024);
3385 if (ret) {
3386 printk(KERN_ERR "Problem removing overlapping space %d\n", ret);
3387 return ret;
3388 }
3389
3390 if (check_exists(cache, 3 * 1024 * 1024, 4 * 1024 * 1024)) {
3391 printk(KERN_ERR "Left something behind when removing space");
3392 return -1;
3393 }
3394
3395 /*
3396 * This has blown up in the past, the extent entry starts before the
3397 * bitmap entry, but we're trying to remove an offset that falls
3398 * completely within the bitmap range and is in both the extent entry
3399 * and the bitmap entry, looks like this
3400 *
3401 * [ extent ]
3402 * [ bitmap ]
3403 * [ del ]
3404 */
3405 __btrfs_remove_free_space_cache(cache->free_space_ctl);
3406 ret = add_free_space_entry(cache, bitmap_offset + 4 * 1024 * 1024,
3407 4 * 1024 * 1024, 1);
3408 if (ret) {
3409 printk(KERN_ERR "Couldn't add bitmap %d\n", ret);
3410 return ret;
3411 }
3412
3413 ret = add_free_space_entry(cache, bitmap_offset - 1 * 1024 * 1024,
3414 5 * 1024 * 1024, 0);
3415 if (ret) {
3416 printk(KERN_ERR "Couldn't add extent entry %d\n", ret);
3417 return ret;
3418 }
3419
3420 ret = btrfs_remove_free_space(cache, bitmap_offset + 1 * 1024 * 1024,
3421 5 * 1024 * 1024);
3422 if (ret) {
3423 printk(KERN_ERR "Failed to free our space %d\n", ret);
3424 return ret;
3425 }
3426
3427 if (check_exists(cache, bitmap_offset + 1 * 1024 * 1024,
3428 5 * 1024 * 1024)) {
3429 printk(KERN_ERR "Left stuff over\n");
3430 return -1;
3431 }
3432
3433 __btrfs_remove_free_space_cache(cache->free_space_ctl);
3434
3435 /*
3436 * This blew up before, we have part of the free space in a bitmap and
3437 * then the entirety of the rest of the space in an extent. This used
3438 * to return -EAGAIN back from btrfs_remove_extent, make sure this
3439 * doesn't happen.
3440 */
3441 ret = add_free_space_entry(cache, 1 * 1024 * 1024, 2 * 1024 * 1024, 1);
3442 if (ret) {
3443 printk(KERN_ERR "Couldn't add bitmap entry %d\n", ret);
3444 return ret;
3445 }
3446
3447 ret = add_free_space_entry(cache, 3 * 1024 * 1024, 1 * 1024 * 1024, 0);
3448 if (ret) {
3449 printk(KERN_ERR "Couldn't add extent entry %d\n", ret);
3450 return ret;
3451 }
3452
3453 ret = btrfs_remove_free_space(cache, 1 * 1024 * 1024, 3 * 1024 * 1024);
3454 if (ret) {
3455 printk(KERN_ERR "Error removing bitmap and extent "
3456 "overlapping %d\n", ret);
3457 return ret;
3458 }
3459
3460 __btrfs_remove_free_space_cache(cache->free_space_ctl);
3461 return 0;
3462}
3463
3464void btrfs_test_free_space_cache(void)
3465{
3466 struct btrfs_block_group_cache *cache;
3467
3468 printk(KERN_ERR "Running btrfs free space cache tests\n");
3469
3470 cache = init_test_block_group();
3471 if (!cache) {
3472 printk(KERN_ERR "Couldn't run the tests\n");
3473 return;
3474 }
3475
3476 if (test_extents(cache))
3477 goto out;
3478 if (test_bitmaps(cache))
3479 goto out;
3480 if (test_bitmaps_and_extents(cache))
3481 goto out;
3482out:
3483 __btrfs_remove_free_space_cache(cache->free_space_ctl);
3484 kfree(cache->free_space_ctl);
3485 kfree(cache);
3486 printk(KERN_ERR "Free space cache tests finished\n");
3487}
3488#endif /* CONFIG_BTRFS_FS_RUN_SANITY_TESTS */
diff --git a/fs/btrfs/free-space-cache.h b/fs/btrfs/free-space-cache.h
index 8f2613f779ed..4dc17d8809c7 100644
--- a/fs/btrfs/free-space-cache.h
+++ b/fs/btrfs/free-space-cache.h
@@ -110,4 +110,9 @@ int btrfs_return_cluster_to_free_space(
110 struct btrfs_free_cluster *cluster); 110 struct btrfs_free_cluster *cluster);
111int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group, 111int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group,
112 u64 *trimmed, u64 start, u64 end, u64 minlen); 112 u64 *trimmed, u64 start, u64 end, u64 minlen);
113
114#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
115void btrfs_test_free_space_cache(void);
116#endif
117
113#endif 118#endif
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index f6b88595f858..714ae479de2e 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -56,6 +56,7 @@
56#include "compression.h" 56#include "compression.h"
57#include "rcu-string.h" 57#include "rcu-string.h"
58#include "dev-replace.h" 58#include "dev-replace.h"
59#include "free-space-cache.h"
59 60
60#define CREATE_TRACE_POINTS 61#define CREATE_TRACE_POINTS
61#include <trace/events/btrfs.h> 62#include <trace/events/btrfs.h>
@@ -1739,6 +1740,10 @@ static int __init init_btrfs_fs(void)
1739 1740
1740 btrfs_init_lockdep(); 1741 btrfs_init_lockdep();
1741 1742
1743#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
1744 btrfs_test_free_space_cache();
1745#endif
1746
1742 printk(KERN_INFO "%s loaded\n", BTRFS_BUILD_VERSION); 1747 printk(KERN_INFO "%s loaded\n", BTRFS_BUILD_VERSION);
1743 return 0; 1748 return 0;
1744 1749