Merge tag 'for-5.2/block-post-20190516' of git://git.kernel.dk/linux-block
[linux-2.6-block.git] / fs / btrfs / tests / btrfs-tests.c
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/magic.h>
9 #include "btrfs-tests.h"
10 #include "../ctree.h"
11 #include "../free-space-cache.h"
12 #include "../free-space-tree.h"
13 #include "../transaction.h"
14 #include "../volumes.h"
15 #include "../disk-io.h"
16 #include "../qgroup.h"
17
18 static struct vfsmount *test_mnt = NULL;
19
20 const char *test_error[] = {
21         [TEST_ALLOC_FS_INFO]         = "cannot allocate fs_info",
22         [TEST_ALLOC_ROOT]            = "cannot allocate root",
23         [TEST_ALLOC_EXTENT_BUFFER]   = "cannot extent buffer",
24         [TEST_ALLOC_PATH]            = "cannot allocate path",
25         [TEST_ALLOC_INODE]           = "cannot allocate inode",
26         [TEST_ALLOC_BLOCK_GROUP]     = "cannot allocate block group",
27         [TEST_ALLOC_EXTENT_MAP]      = "cannot allocate extent map",
28 };
29
30 static const struct super_operations btrfs_test_super_ops = {
31         .alloc_inode    = btrfs_alloc_inode,
32         .destroy_inode  = btrfs_test_destroy_inode,
33 };
34
35 static struct dentry *btrfs_test_mount(struct file_system_type *fs_type,
36                                        int flags, const char *dev_name,
37                                        void *data)
38 {
39         return mount_pseudo(fs_type, "btrfs_test:", &btrfs_test_super_ops,
40                             NULL, BTRFS_TEST_MAGIC);
41 }
42
43 static struct file_system_type test_type = {
44         .name           = "btrfs_test_fs",
45         .mount          = btrfs_test_mount,
46         .kill_sb        = kill_anon_super,
47 };
48
49 struct inode *btrfs_new_test_inode(void)
50 {
51         return new_inode(test_mnt->mnt_sb);
52 }
53
54 static int btrfs_init_test_fs(void)
55 {
56         int ret;
57
58         ret = register_filesystem(&test_type);
59         if (ret) {
60                 printk(KERN_ERR "btrfs: cannot register test file system\n");
61                 return ret;
62         }
63
64         test_mnt = kern_mount(&test_type);
65         if (IS_ERR(test_mnt)) {
66                 printk(KERN_ERR "btrfs: cannot mount test file system\n");
67                 unregister_filesystem(&test_type);
68                 return PTR_ERR(test_mnt);
69         }
70         return 0;
71 }
72
73 static void btrfs_destroy_test_fs(void)
74 {
75         kern_unmount(test_mnt);
76         unregister_filesystem(&test_type);
77 }
78
79 struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(u32 nodesize, u32 sectorsize)
80 {
81         struct btrfs_fs_info *fs_info = kzalloc(sizeof(struct btrfs_fs_info),
82                                                 GFP_KERNEL);
83
84         if (!fs_info)
85                 return fs_info;
86         fs_info->fs_devices = kzalloc(sizeof(struct btrfs_fs_devices),
87                                       GFP_KERNEL);
88         if (!fs_info->fs_devices) {
89                 kfree(fs_info);
90                 return NULL;
91         }
92         fs_info->super_copy = kzalloc(sizeof(struct btrfs_super_block),
93                                       GFP_KERNEL);
94         if (!fs_info->super_copy) {
95                 kfree(fs_info->fs_devices);
96                 kfree(fs_info);
97                 return NULL;
98         }
99
100         fs_info->nodesize = nodesize;
101         fs_info->sectorsize = sectorsize;
102
103         if (init_srcu_struct(&fs_info->subvol_srcu)) {
104                 kfree(fs_info->fs_devices);
105                 kfree(fs_info->super_copy);
106                 kfree(fs_info);
107                 return NULL;
108         }
109
110         spin_lock_init(&fs_info->buffer_lock);
111         spin_lock_init(&fs_info->qgroup_lock);
112         spin_lock_init(&fs_info->super_lock);
113         spin_lock_init(&fs_info->fs_roots_radix_lock);
114         spin_lock_init(&fs_info->tree_mod_seq_lock);
115         mutex_init(&fs_info->qgroup_ioctl_lock);
116         mutex_init(&fs_info->qgroup_rescan_lock);
117         rwlock_init(&fs_info->tree_mod_log_lock);
118         fs_info->running_transaction = NULL;
119         fs_info->qgroup_tree = RB_ROOT;
120         fs_info->qgroup_ulist = NULL;
121         atomic64_set(&fs_info->tree_mod_seq, 0);
122         INIT_LIST_HEAD(&fs_info->dirty_qgroups);
123         INIT_LIST_HEAD(&fs_info->dead_roots);
124         INIT_LIST_HEAD(&fs_info->tree_mod_seq_list);
125         INIT_RADIX_TREE(&fs_info->buffer_radix, GFP_ATOMIC);
126         INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC);
127         extent_io_tree_init(fs_info, &fs_info->freed_extents[0],
128                             IO_TREE_FS_INFO_FREED_EXTENTS0, NULL);
129         extent_io_tree_init(fs_info, &fs_info->freed_extents[1],
130                             IO_TREE_FS_INFO_FREED_EXTENTS1, NULL);
131         fs_info->pinned_extents = &fs_info->freed_extents[0];
132         set_bit(BTRFS_FS_STATE_DUMMY_FS_INFO, &fs_info->fs_state);
133
134         test_mnt->mnt_sb->s_fs_info = fs_info;
135
136         return fs_info;
137 }
138
139 void btrfs_free_dummy_fs_info(struct btrfs_fs_info *fs_info)
140 {
141         struct radix_tree_iter iter;
142         void **slot;
143
144         if (!fs_info)
145                 return;
146
147         if (WARN_ON(!test_bit(BTRFS_FS_STATE_DUMMY_FS_INFO,
148                               &fs_info->fs_state)))
149                 return;
150
151         test_mnt->mnt_sb->s_fs_info = NULL;
152
153         spin_lock(&fs_info->buffer_lock);
154         radix_tree_for_each_slot(slot, &fs_info->buffer_radix, &iter, 0) {
155                 struct extent_buffer *eb;
156
157                 eb = radix_tree_deref_slot_protected(slot, &fs_info->buffer_lock);
158                 if (!eb)
159                         continue;
160                 /* Shouldn't happen but that kind of thinking creates CVE's */
161                 if (radix_tree_exception(eb)) {
162                         if (radix_tree_deref_retry(eb))
163                                 slot = radix_tree_iter_retry(&iter);
164                         continue;
165                 }
166                 slot = radix_tree_iter_resume(slot, &iter);
167                 spin_unlock(&fs_info->buffer_lock);
168                 free_extent_buffer_stale(eb);
169                 spin_lock(&fs_info->buffer_lock);
170         }
171         spin_unlock(&fs_info->buffer_lock);
172
173         btrfs_free_qgroup_config(fs_info);
174         btrfs_free_fs_roots(fs_info);
175         cleanup_srcu_struct(&fs_info->subvol_srcu);
176         kfree(fs_info->super_copy);
177         kfree(fs_info->fs_devices);
178         kfree(fs_info);
179 }
180
181 void btrfs_free_dummy_root(struct btrfs_root *root)
182 {
183         if (!root)
184                 return;
185         /* Will be freed by btrfs_free_fs_roots */
186         if (WARN_ON(test_bit(BTRFS_ROOT_IN_RADIX, &root->state)))
187                 return;
188         if (root->node) {
189                 /* One for allocate_extent_buffer */
190                 free_extent_buffer(root->node);
191         }
192         kfree(root);
193 }
194
195 struct btrfs_block_group_cache *
196 btrfs_alloc_dummy_block_group(struct btrfs_fs_info *fs_info,
197                               unsigned long length)
198 {
199         struct btrfs_block_group_cache *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->key.objectid = 0;
212         cache->key.offset = length;
213         cache->key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
214         cache->full_stripe_len = fs_info->sectorsize;
215         cache->fs_info = fs_info;
216
217         INIT_LIST_HEAD(&cache->list);
218         INIT_LIST_HEAD(&cache->cluster_list);
219         INIT_LIST_HEAD(&cache->bg_list);
220         btrfs_init_free_space_ctl(cache);
221         mutex_init(&cache->free_space_lock);
222
223         return cache;
224 }
225
226 void btrfs_free_dummy_block_group(struct btrfs_block_group_cache *cache)
227 {
228         if (!cache)
229                 return;
230         __btrfs_remove_free_space_cache(cache->free_space_ctl);
231         kfree(cache->free_space_ctl);
232         kfree(cache);
233 }
234
235 void btrfs_init_dummy_trans(struct btrfs_trans_handle *trans,
236                             struct btrfs_fs_info *fs_info)
237 {
238         memset(trans, 0, sizeof(*trans));
239         trans->transid = 1;
240         trans->type = __TRANS_DUMMY;
241         trans->fs_info = fs_info;
242 }
243
244 int btrfs_run_sanity_tests(void)
245 {
246         int ret, i;
247         u32 sectorsize, nodesize;
248         u32 test_sectorsize[] = {
249                 PAGE_SIZE,
250         };
251         ret = btrfs_init_test_fs();
252         if (ret)
253                 return ret;
254         for (i = 0; i < ARRAY_SIZE(test_sectorsize); i++) {
255                 sectorsize = test_sectorsize[i];
256                 for (nodesize = sectorsize;
257                      nodesize <= BTRFS_MAX_METADATA_BLOCKSIZE;
258                      nodesize <<= 1) {
259                         pr_info("BTRFS: selftest: sectorsize: %u  nodesize: %u\n",
260                                 sectorsize, nodesize);
261                         ret = btrfs_test_free_space_cache(sectorsize, nodesize);
262                         if (ret)
263                                 goto out;
264                         ret = btrfs_test_extent_buffer_operations(sectorsize,
265                                 nodesize);
266                         if (ret)
267                                 goto out;
268                         ret = btrfs_test_extent_io(sectorsize, nodesize);
269                         if (ret)
270                                 goto out;
271                         ret = btrfs_test_inodes(sectorsize, nodesize);
272                         if (ret)
273                                 goto out;
274                         ret = btrfs_test_qgroups(sectorsize, nodesize);
275                         if (ret)
276                                 goto out;
277                         ret = btrfs_test_free_space_tree(sectorsize, nodesize);
278                         if (ret)
279                                 goto out;
280                 }
281         }
282         ret = btrfs_test_extent_map();
283
284 out:
285         btrfs_destroy_test_fs();
286         return ret;
287 }