cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

btrfs-tests.c (6841B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (C) 2013 Fusion IO.  All rights reserved.
      4 */
      5
      6#include <linux/fs.h>
      7#include <linux/mount.h>
      8#include <linux/pseudo_fs.h>
      9#include <linux/magic.h>
     10#include "btrfs-tests.h"
     11#include "../ctree.h"
     12#include "../free-space-cache.h"
     13#include "../free-space-tree.h"
     14#include "../transaction.h"
     15#include "../volumes.h"
     16#include "../disk-io.h"
     17#include "../qgroup.h"
     18#include "../block-group.h"
     19
     20static struct vfsmount *test_mnt = NULL;
     21
     22const char *test_error[] = {
     23	[TEST_ALLOC_FS_INFO]	     = "cannot allocate fs_info",
     24	[TEST_ALLOC_ROOT]	     = "cannot allocate root",
     25	[TEST_ALLOC_EXTENT_BUFFER]   = "cannot extent buffer",
     26	[TEST_ALLOC_PATH]	     = "cannot allocate path",
     27	[TEST_ALLOC_INODE]	     = "cannot allocate inode",
     28	[TEST_ALLOC_BLOCK_GROUP]     = "cannot allocate block group",
     29	[TEST_ALLOC_EXTENT_MAP]      = "cannot allocate extent map",
     30};
     31
     32static const struct super_operations btrfs_test_super_ops = {
     33	.alloc_inode	= btrfs_alloc_inode,
     34	.destroy_inode	= btrfs_test_destroy_inode,
     35};
     36
     37
     38static int btrfs_test_init_fs_context(struct fs_context *fc)
     39{
     40	struct pseudo_fs_context *ctx = init_pseudo(fc, BTRFS_TEST_MAGIC);
     41	if (!ctx)
     42		return -ENOMEM;
     43	ctx->ops = &btrfs_test_super_ops;
     44	return 0;
     45}
     46
     47static struct file_system_type test_type = {
     48	.name		= "btrfs_test_fs",
     49	.init_fs_context = btrfs_test_init_fs_context,
     50	.kill_sb	= kill_anon_super,
     51};
     52
     53struct inode *btrfs_new_test_inode(void)
     54{
     55	struct inode *inode;
     56
     57	inode = new_inode(test_mnt->mnt_sb);
     58	if (!inode)
     59		return NULL;
     60
     61	inode->i_mode = S_IFREG;
     62	BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY;
     63	BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID;
     64	BTRFS_I(inode)->location.offset = 0;
     65	inode_init_owner(&init_user_ns, inode, NULL, S_IFREG);
     66
     67	return inode;
     68}
     69
     70static int btrfs_init_test_fs(void)
     71{
     72	int ret;
     73
     74	ret = register_filesystem(&test_type);
     75	if (ret) {
     76		printk(KERN_ERR "btrfs: cannot register test file system\n");
     77		return ret;
     78	}
     79
     80	test_mnt = kern_mount(&test_type);
     81	if (IS_ERR(test_mnt)) {
     82		printk(KERN_ERR "btrfs: cannot mount test file system\n");
     83		unregister_filesystem(&test_type);
     84		return PTR_ERR(test_mnt);
     85	}
     86	return 0;
     87}
     88
     89static void btrfs_destroy_test_fs(void)
     90{
     91	kern_unmount(test_mnt);
     92	unregister_filesystem(&test_type);
     93}
     94
     95struct btrfs_device *btrfs_alloc_dummy_device(struct btrfs_fs_info *fs_info)
     96{
     97	struct btrfs_device *dev;
     98
     99	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
    100	if (!dev)
    101		return ERR_PTR(-ENOMEM);
    102
    103	extent_io_tree_init(NULL, &dev->alloc_state, 0, NULL);
    104	INIT_LIST_HEAD(&dev->dev_list);
    105	list_add(&dev->dev_list, &fs_info->fs_devices->devices);
    106
    107	return dev;
    108}
    109
    110static void btrfs_free_dummy_device(struct btrfs_device *dev)
    111{
    112	extent_io_tree_release(&dev->alloc_state);
    113	kfree(dev);
    114}
    115
    116struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(u32 nodesize, u32 sectorsize)
    117{
    118	struct btrfs_fs_info *fs_info = kzalloc(sizeof(struct btrfs_fs_info),
    119						GFP_KERNEL);
    120
    121	if (!fs_info)
    122		return fs_info;
    123	fs_info->fs_devices = kzalloc(sizeof(struct btrfs_fs_devices),
    124				      GFP_KERNEL);
    125	if (!fs_info->fs_devices) {
    126		kfree(fs_info);
    127		return NULL;
    128	}
    129	INIT_LIST_HEAD(&fs_info->fs_devices->devices);
    130
    131	fs_info->super_copy = kzalloc(sizeof(struct btrfs_super_block),
    132				      GFP_KERNEL);
    133	if (!fs_info->super_copy) {
    134		kfree(fs_info->fs_devices);
    135		kfree(fs_info);
    136		return NULL;
    137	}
    138
    139	btrfs_init_fs_info(fs_info);
    140
    141	fs_info->nodesize = nodesize;
    142	fs_info->sectorsize = sectorsize;
    143	fs_info->sectorsize_bits = ilog2(sectorsize);
    144	set_bit(BTRFS_FS_STATE_DUMMY_FS_INFO, &fs_info->fs_state);
    145
    146	test_mnt->mnt_sb->s_fs_info = fs_info;
    147
    148	return fs_info;
    149}
    150
    151void btrfs_free_dummy_fs_info(struct btrfs_fs_info *fs_info)
    152{
    153	unsigned long index;
    154	struct extent_buffer *eb;
    155	struct btrfs_device *dev, *tmp;
    156
    157	if (!fs_info)
    158		return;
    159
    160	if (WARN_ON(!test_bit(BTRFS_FS_STATE_DUMMY_FS_INFO,
    161			      &fs_info->fs_state)))
    162		return;
    163
    164	test_mnt->mnt_sb->s_fs_info = NULL;
    165
    166	xa_for_each(&fs_info->extent_buffers, index, eb) {
    167		free_extent_buffer_stale(eb);
    168	}
    169
    170	btrfs_mapping_tree_free(&fs_info->mapping_tree);
    171	list_for_each_entry_safe(dev, tmp, &fs_info->fs_devices->devices,
    172				 dev_list) {
    173		btrfs_free_dummy_device(dev);
    174	}
    175	btrfs_free_qgroup_config(fs_info);
    176	btrfs_free_fs_roots(fs_info);
    177	kfree(fs_info->super_copy);
    178	btrfs_check_leaked_roots(fs_info);
    179	btrfs_extent_buffer_leak_debug_check(fs_info);
    180	kfree(fs_info->fs_devices);
    181	kfree(fs_info);
    182}
    183
    184void btrfs_free_dummy_root(struct btrfs_root *root)
    185{
    186	if (!root)
    187		return;
    188	/* Will be freed by btrfs_free_fs_roots */
    189	if (WARN_ON(test_bit(BTRFS_ROOT_REGISTERED, &root->state)))
    190		return;
    191	btrfs_global_root_delete(root);
    192	btrfs_put_root(root);
    193}
    194
    195struct btrfs_block_group *
    196btrfs_alloc_dummy_block_group(struct btrfs_fs_info *fs_info,
    197			      unsigned long length)
    198{
    199	struct btrfs_block_group *cache;
    200
    201	cache = kzalloc(sizeof(*cache), GFP_KERNEL);
    202	if (!cache)
    203		return NULL;
    204	cache->free_space_ctl = kzalloc(sizeof(*cache->free_space_ctl),
    205					GFP_KERNEL);
    206	if (!cache->free_space_ctl) {
    207		kfree(cache);
    208		return NULL;
    209	}
    210
    211	cache->start = 0;
    212	cache->length = length;
    213	cache->full_stripe_len = fs_info->sectorsize;
    214	cache->fs_info = fs_info;
    215
    216	INIT_LIST_HEAD(&cache->list);
    217	INIT_LIST_HEAD(&cache->cluster_list);
    218	INIT_LIST_HEAD(&cache->bg_list);
    219	btrfs_init_free_space_ctl(cache, cache->free_space_ctl);
    220	mutex_init(&cache->free_space_lock);
    221
    222	return cache;
    223}
    224
    225void btrfs_free_dummy_block_group(struct btrfs_block_group *cache)
    226{
    227	if (!cache)
    228		return;
    229	__btrfs_remove_free_space_cache(cache->free_space_ctl);
    230	kfree(cache->free_space_ctl);
    231	kfree(cache);
    232}
    233
    234void btrfs_init_dummy_trans(struct btrfs_trans_handle *trans,
    235			    struct btrfs_fs_info *fs_info)
    236{
    237	memset(trans, 0, sizeof(*trans));
    238	trans->transid = 1;
    239	trans->type = __TRANS_DUMMY;
    240	trans->fs_info = fs_info;
    241}
    242
    243int btrfs_run_sanity_tests(void)
    244{
    245	int ret, i;
    246	u32 sectorsize, nodesize;
    247	u32 test_sectorsize[] = {
    248		PAGE_SIZE,
    249	};
    250	ret = btrfs_init_test_fs();
    251	if (ret)
    252		return ret;
    253	for (i = 0; i < ARRAY_SIZE(test_sectorsize); i++) {
    254		sectorsize = test_sectorsize[i];
    255		for (nodesize = sectorsize;
    256		     nodesize <= BTRFS_MAX_METADATA_BLOCKSIZE;
    257		     nodesize <<= 1) {
    258			pr_info("BTRFS: selftest: sectorsize: %u  nodesize: %u\n",
    259				sectorsize, nodesize);
    260			ret = btrfs_test_free_space_cache(sectorsize, nodesize);
    261			if (ret)
    262				goto out;
    263			ret = btrfs_test_extent_buffer_operations(sectorsize,
    264				nodesize);
    265			if (ret)
    266				goto out;
    267			ret = btrfs_test_extent_io(sectorsize, nodesize);
    268			if (ret)
    269				goto out;
    270			ret = btrfs_test_inodes(sectorsize, nodesize);
    271			if (ret)
    272				goto out;
    273			ret = btrfs_test_qgroups(sectorsize, nodesize);
    274			if (ret)
    275				goto out;
    276			ret = btrfs_test_free_space_tree(sectorsize, nodesize);
    277			if (ret)
    278				goto out;
    279		}
    280	}
    281	ret = btrfs_test_extent_map();
    282
    283out:
    284	btrfs_destroy_test_fs();
    285	return ret;
    286}