Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2013 Fusion IO.  All rights reserved.
0004  */
0005 
0006 #include <linux/slab.h>
0007 #include "btrfs-tests.h"
0008 #include "../ctree.h"
0009 #include "../extent_io.h"
0010 #include "../disk-io.h"
0011 
0012 static int test_btrfs_split_item(u32 sectorsize, u32 nodesize)
0013 {
0014     struct btrfs_fs_info *fs_info;
0015     struct btrfs_path *path = NULL;
0016     struct btrfs_root *root = NULL;
0017     struct extent_buffer *eb;
0018     char *value = "mary had a little lamb";
0019     char *split1 = "mary had a little";
0020     char *split2 = " lamb";
0021     char *split3 = "mary";
0022     char *split4 = " had a little";
0023     char buf[32];
0024     struct btrfs_key key;
0025     u32 value_len = strlen(value);
0026     int ret = 0;
0027 
0028     test_msg("running btrfs_split_item tests");
0029 
0030     fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
0031     if (!fs_info) {
0032         test_std_err(TEST_ALLOC_FS_INFO);
0033         return -ENOMEM;
0034     }
0035 
0036     root = btrfs_alloc_dummy_root(fs_info);
0037     if (IS_ERR(root)) {
0038         test_std_err(TEST_ALLOC_ROOT);
0039         ret = PTR_ERR(root);
0040         goto out;
0041     }
0042 
0043     path = btrfs_alloc_path();
0044     if (!path) {
0045         test_std_err(TEST_ALLOC_PATH);
0046         ret = -ENOMEM;
0047         goto out;
0048     }
0049 
0050     eb = alloc_dummy_extent_buffer(fs_info, nodesize);
0051     path->nodes[0] = eb;
0052     if (!eb) {
0053         test_std_err(TEST_ALLOC_EXTENT_BUFFER);
0054         ret = -ENOMEM;
0055         goto out;
0056     }
0057     path->slots[0] = 0;
0058 
0059     key.objectid = 0;
0060     key.type = BTRFS_EXTENT_CSUM_KEY;
0061     key.offset = 0;
0062 
0063     btrfs_setup_item_for_insert(root, path, &key, value_len);
0064     write_extent_buffer(eb, value, btrfs_item_ptr_offset(eb, 0),
0065                 value_len);
0066 
0067     key.offset = 3;
0068 
0069     /*
0070      * Passing NULL trans here should be safe because we have plenty of
0071      * space in this leaf to split the item without having to split the
0072      * leaf.
0073      */
0074     ret = btrfs_split_item(NULL, root, path, &key, 17);
0075     if (ret) {
0076         test_err("split item failed %d", ret);
0077         goto out;
0078     }
0079 
0080     /*
0081      * Read the first slot, it should have the original key and contain only
0082      * 'mary had a little'
0083      */
0084     btrfs_item_key_to_cpu(eb, &key, 0);
0085     if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY ||
0086         key.offset != 0) {
0087         test_err("invalid key at slot 0");
0088         ret = -EINVAL;
0089         goto out;
0090     }
0091 
0092     if (btrfs_item_size(eb, 0) != strlen(split1)) {
0093         test_err("invalid len in the first split");
0094         ret = -EINVAL;
0095         goto out;
0096     }
0097 
0098     read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 0),
0099                strlen(split1));
0100     if (memcmp(buf, split1, strlen(split1))) {
0101         test_err(
0102 "data in the buffer doesn't match what it should in the first split have='%.*s' want '%s'",
0103              (int)strlen(split1), buf, split1);
0104         ret = -EINVAL;
0105         goto out;
0106     }
0107 
0108     btrfs_item_key_to_cpu(eb, &key, 1);
0109     if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY ||
0110         key.offset != 3) {
0111         test_err("invalid key at slot 1");
0112         ret = -EINVAL;
0113         goto out;
0114     }
0115 
0116     if (btrfs_item_size(eb, 1) != strlen(split2)) {
0117         test_err("invalid len in the second split");
0118         ret = -EINVAL;
0119         goto out;
0120     }
0121 
0122     read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 1),
0123                strlen(split2));
0124     if (memcmp(buf, split2, strlen(split2))) {
0125         test_err(
0126     "data in the buffer doesn't match what it should in the second split");
0127         ret = -EINVAL;
0128         goto out;
0129     }
0130 
0131     key.offset = 1;
0132     /* Do it again so we test memmoving the other items in the leaf */
0133     ret = btrfs_split_item(NULL, root, path, &key, 4);
0134     if (ret) {
0135         test_err("second split item failed %d", ret);
0136         goto out;
0137     }
0138 
0139     btrfs_item_key_to_cpu(eb, &key, 0);
0140     if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY ||
0141         key.offset != 0) {
0142         test_err("invalid key at slot 0");
0143         ret = -EINVAL;
0144         goto out;
0145     }
0146 
0147     if (btrfs_item_size(eb, 0) != strlen(split3)) {
0148         test_err("invalid len in the first split");
0149         ret = -EINVAL;
0150         goto out;
0151     }
0152 
0153     read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 0),
0154                strlen(split3));
0155     if (memcmp(buf, split3, strlen(split3))) {
0156         test_err(
0157     "data in the buffer doesn't match what it should in the third split");
0158         ret = -EINVAL;
0159         goto out;
0160     }
0161 
0162     btrfs_item_key_to_cpu(eb, &key, 1);
0163     if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY ||
0164         key.offset != 1) {
0165         test_err("invalid key at slot 1");
0166         ret = -EINVAL;
0167         goto out;
0168     }
0169 
0170     if (btrfs_item_size(eb, 1) != strlen(split4)) {
0171         test_err("invalid len in the second split");
0172         ret = -EINVAL;
0173         goto out;
0174     }
0175 
0176     read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 1),
0177                strlen(split4));
0178     if (memcmp(buf, split4, strlen(split4))) {
0179         test_err(
0180     "data in the buffer doesn't match what it should in the fourth split");
0181         ret = -EINVAL;
0182         goto out;
0183     }
0184 
0185     btrfs_item_key_to_cpu(eb, &key, 2);
0186     if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY ||
0187         key.offset != 3) {
0188         test_err("invalid key at slot 2");
0189         ret = -EINVAL;
0190         goto out;
0191     }
0192 
0193     if (btrfs_item_size(eb, 2) != strlen(split2)) {
0194         test_err("invalid len in the second split");
0195         ret = -EINVAL;
0196         goto out;
0197     }
0198 
0199     read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 2),
0200                strlen(split2));
0201     if (memcmp(buf, split2, strlen(split2))) {
0202         test_err(
0203     "data in the buffer doesn't match what it should in the last chunk");
0204         ret = -EINVAL;
0205         goto out;
0206     }
0207 out:
0208     btrfs_free_path(path);
0209     btrfs_free_dummy_root(root);
0210     btrfs_free_dummy_fs_info(fs_info);
0211     return ret;
0212 }
0213 
0214 int btrfs_test_extent_buffer_operations(u32 sectorsize, u32 nodesize)
0215 {
0216     test_msg("running extent buffer operation tests");
0217     return test_btrfs_split_item(sectorsize, nodesize);
0218 }