}
-static bool use_bitmap(struct btrfs_free_space_ctl *ctl,
+EXPORT_FOR_TESTS
+bool btrfs_use_bitmap(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info)
{
struct btrfs_block_group *block_group = ctl->block_group;
return true;
}
-static const struct btrfs_free_space_op free_space_op = {
- .use_bitmap = use_bitmap,
-};
-
static int insert_into_bitmap(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info)
{
struct btrfs_free_space *bitmap_info;
- struct btrfs_block_group *block_group = NULL;
+ struct btrfs_block_group *block_group = ctl->block_group;
int added = 0;
u64 bytes, offset, bytes_added;
enum btrfs_trim_state trim_state;
offset = info->offset;
trim_state = info->trim_state;
- if (!ctl->op->use_bitmap(ctl, info))
- return 0;
-
- if (ctl->op == &free_space_op)
- block_group = ctl->block_group;
+ if (btrfs_is_testing(block_group->fs_info)) {
+ if (!block_group->fs_info->use_bitmap(ctl, info))
+ return 0;
+ } else {
+ if (!btrfs_use_bitmap(ctl, info))
+ return 0;
+ }
again:
/*
* Since we link bitmaps right into the cluster we need to see if we
* have a cluster here, and if so and it has our bitmap we need to add
* the free space to that bitmap.
*/
- if (block_group && !list_empty(&block_group->cluster_list)) {
+ if (!list_empty(&block_group->cluster_list)) {
struct btrfs_free_cluster *cluster;
struct rb_node *node;
struct btrfs_free_space *entry;
{
spin_lock_init(&ctl->tree_lock);
ctl->block_group = block_group;
- ctl->op = &free_space_op;
ctl->free_space_bytes = RB_ROOT_CACHED;
INIT_LIST_HEAD(&ctl->trimming_ranges);
mutex_init(&ctl->cache_writeout_mutex);
u64 free_space;
s32 discardable_extents[BTRFS_STAT_NR_ENTRIES];
s64 discardable_bytes[BTRFS_STAT_NR_ENTRIES];
- const struct btrfs_free_space_op *op;
struct btrfs_block_group *block_group;
struct mutex cache_writeout_mutex;
struct list_head trimming_ranges;
};
-struct btrfs_free_space_op {
- bool (*use_bitmap)(struct btrfs_free_space_ctl *ctl,
- struct btrfs_free_space *info);
-};
-
struct btrfs_io_ctl {
void *cur, *orig;
struct page *page;
int btrfs_set_free_space_cache_v1_active(struct btrfs_fs_info *fs_info, bool active);
/* Support functions for running our sanity tests */
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
+bool btrfs_use_bitmap(struct btrfs_free_space_ctl *ctl,
+ struct btrfs_free_space *info);
int test_add_free_space_entry(struct btrfs_block_group *cache,
u64 offset, u64 bytes, bool bitmap);
int test_check_exists(struct btrfs_block_group *cache, u64 offset, u64 bytes);
wait_queue_head_t wait;
};
+struct btrfs_free_space_ctl;
+struct btrfs_free_space;
+
struct btrfs_fs_info {
u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
unsigned long flags;
spinlock_t eb_leak_lock;
struct list_head allocated_ebs;
#endif
+
+ /* Used by self tests only. */
+ bool (*use_bitmap)(struct btrfs_free_space_ctl *ctl,
+ struct btrfs_free_space *info);
};
#define folio_to_inode(_folio) (BTRFS_I(_Generic((_folio), \
fs_info->csum_size = 4;
fs_info->csums_per_leaf = BTRFS_MAX_ITEM_SIZE(fs_info) /
fs_info->csum_size;
+ fs_info->use_bitmap = btrfs_use_bitmap;
set_bit(BTRFS_FS_STATE_DUMMY_FS_INFO, &fs_info->fs_state);
test_mnt->mnt_sb->s_fs_info = fs_info;
int ret;
u64 offset;
u64 max_extent_size;
- const struct btrfs_free_space_op test_free_space_ops = {
- .use_bitmap = test_use_bitmap,
- };
- const struct btrfs_free_space_op *orig_free_space_ops;
+ bool (*orig_use_bitmap)(struct btrfs_free_space_ctl *ctl,
+ struct btrfs_free_space *info);
test_msg("running space stealing from bitmap to extent tests");
* that forces use of bitmaps as soon as we have at least 1
* extent entry.
*/
- orig_free_space_ops = cache->free_space_ctl->op;
- cache->free_space_ctl->op = &test_free_space_ops;
+ orig_use_bitmap = cache->fs_info->use_bitmap;
+ cache->fs_info->use_bitmap = test_use_bitmap;
/*
* Extent entry covering free space range [128Mb - 256Kb, 128Mb - 128Kb[
if (ret)
return ret;
- cache->free_space_ctl->op = orig_free_space_ops;
+ cache->fs_info->use_bitmap = orig_use_bitmap;
btrfs_remove_free_space_cache(cache);
return 0;
static int test_bytes_index(struct btrfs_block_group *cache, u32 sectorsize)
{
- const struct btrfs_free_space_op test_free_space_ops = {
- .use_bitmap = bytes_index_use_bitmap,
- };
- const struct btrfs_free_space_op *orig_free_space_ops;
+ bool (*orig_use_bitmap)(struct btrfs_free_space_ctl *ctl,
+ struct btrfs_free_space *info);
struct btrfs_free_space_ctl *ctl = cache->free_space_ctl;
struct btrfs_free_space *entry;
struct rb_node *node;
/* Now validate bitmaps with different ->max_extent_size. */
btrfs_remove_free_space_cache(cache);
- orig_free_space_ops = cache->free_space_ctl->op;
- cache->free_space_ctl->op = &test_free_space_ops;
+ orig_use_bitmap = cache->fs_info->use_bitmap;
+ cache->fs_info->use_bitmap = bytes_index_use_bitmap;
ret = test_add_free_space_entry(cache, 0, sectorsize, 1);
if (ret) {
return -EINVAL;
}
- cache->free_space_ctl->op = orig_free_space_ops;
+ cache->fs_info->use_bitmap = orig_use_bitmap;
btrfs_remove_free_space_cache(cache);
return 0;
}