]> Git Repo - linux.git/blobdiff - fs/btrfs/tests/btrfs-tests.c
Btrfs: add sanity tests for new qgroup accounting code
[linux.git] / fs / btrfs / tests / btrfs-tests.c
index 757ef00a75a4da0c088be4c16b58f12f6ec20ede..a5dcacb5df9cc16027240549101e078c03b9220f 100644 (file)
@@ -21,6 +21,9 @@
 #include <linux/magic.h>
 #include "btrfs-tests.h"
 #include "../ctree.h"
+#include "../volumes.h"
+#include "../disk-io.h"
+#include "../qgroup.h"
 
 static struct vfsmount *test_mnt = NULL;
 
@@ -72,3 +75,97 @@ void btrfs_destroy_test_fs(void)
        kern_unmount(test_mnt);
        unregister_filesystem(&test_type);
 }
+
+struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(void)
+{
+       struct btrfs_fs_info *fs_info = kzalloc(sizeof(struct btrfs_fs_info),
+                                               GFP_NOFS);
+
+       if (!fs_info)
+               return fs_info;
+       fs_info->fs_devices = kzalloc(sizeof(struct btrfs_fs_devices),
+                                     GFP_NOFS);
+       if (!fs_info->fs_devices) {
+               kfree(fs_info);
+               return NULL;
+       }
+       fs_info->super_copy = kzalloc(sizeof(struct btrfs_super_block),
+                                     GFP_NOFS);
+       if (!fs_info->super_copy) {
+               kfree(fs_info->fs_devices);
+               kfree(fs_info);
+               return NULL;
+       }
+
+       if (init_srcu_struct(&fs_info->subvol_srcu)) {
+               kfree(fs_info->fs_devices);
+               kfree(fs_info->super_copy);
+               kfree(fs_info);
+               return NULL;
+       }
+
+       spin_lock_init(&fs_info->buffer_lock);
+       spin_lock_init(&fs_info->qgroup_lock);
+       spin_lock_init(&fs_info->qgroup_op_lock);
+       spin_lock_init(&fs_info->super_lock);
+       spin_lock_init(&fs_info->fs_roots_radix_lock);
+       spin_lock_init(&fs_info->tree_mod_seq_lock);
+       mutex_init(&fs_info->qgroup_ioctl_lock);
+       mutex_init(&fs_info->qgroup_rescan_lock);
+       rwlock_init(&fs_info->tree_mod_log_lock);
+       fs_info->running_transaction = NULL;
+       fs_info->qgroup_tree = RB_ROOT;
+       fs_info->qgroup_ulist = NULL;
+       atomic64_set(&fs_info->tree_mod_seq, 0);
+       INIT_LIST_HEAD(&fs_info->dirty_qgroups);
+       INIT_LIST_HEAD(&fs_info->dead_roots);
+       INIT_LIST_HEAD(&fs_info->tree_mod_seq_list);
+       INIT_RADIX_TREE(&fs_info->buffer_radix, GFP_ATOMIC);
+       INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC);
+       return fs_info;
+}
+
+static void btrfs_free_dummy_fs_info(struct btrfs_fs_info *fs_info)
+{
+       struct radix_tree_iter iter;
+       void **slot;
+
+       spin_lock(&fs_info->buffer_lock);
+restart:
+       radix_tree_for_each_slot(slot, &fs_info->buffer_radix, &iter, 0) {
+               struct extent_buffer *eb;
+
+               eb = radix_tree_deref_slot(slot);
+               if (!eb)
+                       continue;
+               /* Shouldn't happen but that kind of thinking creates CVE's */
+               if (radix_tree_exception(eb)) {
+                       if (radix_tree_deref_retry(eb))
+                               goto restart;
+                       continue;
+               }
+               spin_unlock(&fs_info->buffer_lock);
+               free_extent_buffer_stale(eb);
+               spin_lock(&fs_info->buffer_lock);
+       }
+       spin_unlock(&fs_info->buffer_lock);
+
+       btrfs_free_qgroup_config(fs_info);
+       btrfs_free_fs_roots(fs_info);
+       cleanup_srcu_struct(&fs_info->subvol_srcu);
+       kfree(fs_info->super_copy);
+       kfree(fs_info->fs_devices);
+       kfree(fs_info);
+}
+
+void btrfs_free_dummy_root(struct btrfs_root *root)
+{
+       if (!root)
+               return;
+       if (root->node)
+               free_extent_buffer(root->node);
+       if (root->fs_info)
+               btrfs_free_dummy_fs_info(root->fs_info);
+       kfree(root);
+}
+
This page took 0.037487 seconds and 4 git commands to generate.