linux/fs/btrfs/tests/extent-buffer-tests.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2013 Fusion IO.  All rights reserved.
   3 *
   4 * This program is free software; you can redistribute it and/or
   5 * modify it under the terms of the GNU General Public
   6 * License v2 as published by the Free Software Foundation.
   7 *
   8 * This program is distributed in the hope that it will be useful,
   9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11 * General Public License for more details.
  12 *
  13 * You should have received a copy of the GNU General Public
  14 * License along with this program; if not, write to the
  15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  16 * Boston, MA 021110-1307, USA.
  17 */
  18
  19#include <linux/slab.h>
  20#include "btrfs-tests.h"
  21#include "../ctree.h"
  22#include "../extent_io.h"
  23#include "../disk-io.h"
  24
  25static int test_btrfs_split_item(u32 sectorsize, u32 nodesize)
  26{
  27        struct btrfs_fs_info *fs_info;
  28        struct btrfs_path *path = NULL;
  29        struct btrfs_root *root = NULL;
  30        struct extent_buffer *eb;
  31        struct btrfs_item *item;
  32        char *value = "mary had a little lamb";
  33        char *split1 = "mary had a little";
  34        char *split2 = " lamb";
  35        char *split3 = "mary";
  36        char *split4 = " had a little";
  37        char buf[32];
  38        struct btrfs_key key;
  39        u32 value_len = strlen(value);
  40        int ret = 0;
  41
  42        test_msg("Running btrfs_split_item tests\n");
  43
  44        fs_info = btrfs_alloc_dummy_fs_info();
  45        if (!fs_info) {
  46                test_msg("Could not allocate fs_info\n");
  47                return -ENOMEM;
  48        }
  49
  50        root = btrfs_alloc_dummy_root(fs_info, sectorsize, nodesize);
  51        if (IS_ERR(root)) {
  52                test_msg("Could not allocate root\n");
  53                ret = PTR_ERR(root);
  54                goto out;
  55        }
  56
  57        path = btrfs_alloc_path();
  58        if (!path) {
  59                test_msg("Could not allocate path\n");
  60                ret = -ENOMEM;
  61                goto out;
  62        }
  63
  64        path->nodes[0] = eb = alloc_dummy_extent_buffer(NULL, nodesize,
  65                                                        nodesize);
  66        if (!eb) {
  67                test_msg("Could not allocate dummy buffer\n");
  68                ret = -ENOMEM;
  69                goto out;
  70        }
  71        path->slots[0] = 0;
  72
  73        key.objectid = 0;
  74        key.type = BTRFS_EXTENT_CSUM_KEY;
  75        key.offset = 0;
  76
  77        setup_items_for_insert(root, path, &key, &value_len, value_len,
  78                               value_len + sizeof(struct btrfs_item), 1);
  79        item = btrfs_item_nr(0);
  80        write_extent_buffer(eb, value, btrfs_item_ptr_offset(eb, 0),
  81                            value_len);
  82
  83        key.offset = 3;
  84
  85        /*
  86         * Passing NULL trans here should be safe because we have plenty of
  87         * space in this leaf to split the item without having to split the
  88         * leaf.
  89         */
  90        ret = btrfs_split_item(NULL, root, path, &key, 17);
  91        if (ret) {
  92                test_msg("Split item failed %d\n", ret);
  93                goto out;
  94        }
  95
  96        /*
  97         * Read the first slot, it should have the original key and contain only
  98         * 'mary had a little'
  99         */
 100        btrfs_item_key_to_cpu(eb, &key, 0);
 101        if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY ||
 102            key.offset != 0) {
 103                test_msg("Invalid key at slot 0\n");
 104                ret = -EINVAL;
 105                goto out;
 106        }
 107
 108        item = btrfs_item_nr(0);
 109        if (btrfs_item_size(eb, item) != strlen(split1)) {
 110                test_msg("Invalid len in the first split\n");
 111                ret = -EINVAL;
 112                goto out;
 113        }
 114
 115        read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 0),
 116                           strlen(split1));
 117        if (memcmp(buf, split1, strlen(split1))) {
 118                test_msg("Data in the buffer doesn't match what it should "
 119                         "in the first split have='%.*s' want '%s'\n",
 120                         (int)strlen(split1), buf, split1);
 121                ret = -EINVAL;
 122                goto out;
 123        }
 124
 125        btrfs_item_key_to_cpu(eb, &key, 1);
 126        if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY ||
 127            key.offset != 3) {
 128                test_msg("Invalid key at slot 1\n");
 129                ret = -EINVAL;
 130                goto out;
 131        }
 132
 133        item = btrfs_item_nr(1);
 134        if (btrfs_item_size(eb, item) != strlen(split2)) {
 135                test_msg("Invalid len in the second split\n");
 136                ret = -EINVAL;
 137                goto out;
 138        }
 139
 140        read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 1),
 141                           strlen(split2));
 142        if (memcmp(buf, split2, strlen(split2))) {
 143                test_msg("Data in the buffer doesn't match what it should "
 144                         "in the second split\n");
 145                ret = -EINVAL;
 146                goto out;
 147        }
 148
 149        key.offset = 1;
 150        /* Do it again so we test memmoving the other items in the leaf */
 151        ret = btrfs_split_item(NULL, root, path, &key, 4);
 152        if (ret) {
 153                test_msg("Second split item failed %d\n", ret);
 154                goto out;
 155        }
 156
 157        btrfs_item_key_to_cpu(eb, &key, 0);
 158        if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY ||
 159            key.offset != 0) {
 160                test_msg("Invalid key at slot 0\n");
 161                ret = -EINVAL;
 162                goto out;
 163        }
 164
 165        item = btrfs_item_nr(0);
 166        if (btrfs_item_size(eb, item) != strlen(split3)) {
 167                test_msg("Invalid len in the first split\n");
 168                ret = -EINVAL;
 169                goto out;
 170        }
 171
 172        read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 0),
 173                           strlen(split3));
 174        if (memcmp(buf, split3, strlen(split3))) {
 175                test_msg("Data in the buffer doesn't match what it should "
 176                         "in the third split");
 177                ret = -EINVAL;
 178                goto out;
 179        }
 180
 181        btrfs_item_key_to_cpu(eb, &key, 1);
 182        if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY ||
 183            key.offset != 1) {
 184                test_msg("Invalid key at slot 1\n");
 185                ret = -EINVAL;
 186                goto out;
 187        }
 188
 189        item = btrfs_item_nr(1);
 190        if (btrfs_item_size(eb, item) != strlen(split4)) {
 191                test_msg("Invalid len in the second split\n");
 192                ret = -EINVAL;
 193                goto out;
 194        }
 195
 196        read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 1),
 197                           strlen(split4));
 198        if (memcmp(buf, split4, strlen(split4))) {
 199                test_msg("Data in the buffer doesn't match what it should "
 200                         "in the fourth split\n");
 201                ret = -EINVAL;
 202                goto out;
 203        }
 204
 205        btrfs_item_key_to_cpu(eb, &key, 2);
 206        if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY ||
 207            key.offset != 3) {
 208                test_msg("Invalid key at slot 2\n");
 209                ret = -EINVAL;
 210                goto out;
 211        }
 212
 213        item = btrfs_item_nr(2);
 214        if (btrfs_item_size(eb, item) != strlen(split2)) {
 215                test_msg("Invalid len in the second split\n");
 216                ret = -EINVAL;
 217                goto out;
 218        }
 219
 220        read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 2),
 221                           strlen(split2));
 222        if (memcmp(buf, split2, strlen(split2))) {
 223                test_msg("Data in the buffer doesn't match what it should "
 224                         "in the last chunk\n");
 225                ret = -EINVAL;
 226                goto out;
 227        }
 228out:
 229        btrfs_free_path(path);
 230        btrfs_free_dummy_root(root);
 231        btrfs_free_dummy_fs_info(fs_info);
 232        return ret;
 233}
 234
 235int btrfs_test_extent_buffer_operations(u32 sectorsize, u32 nodesize)
 236{
 237        test_msg("Running extent buffer operation tests\n");
 238        return test_btrfs_split_item(sectorsize, nodesize);
 239}
 240