Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / fs / btrfs / tests / extent-buffer-tests.c
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
25 static int test_btrfs_split_item(void)
26 {
27         struct btrfs_path *path;
28         struct btrfs_root *root;
29         struct extent_buffer *eb;
30         struct btrfs_item *item;
31         char *value = "mary had a little lamb";
32         char *split1 = "mary had a little";
33         char *split2 = " lamb";
34         char *split3 = "mary";
35         char *split4 = " had a little";
36         char buf[32];
37         struct btrfs_key key;
38         u32 value_len = strlen(value);
39         int ret = 0;
40
41         test_msg("Running btrfs_split_item tests\n");
42
43         root = btrfs_alloc_dummy_root();
44         if (IS_ERR(root)) {
45                 test_msg("Could not allocate root\n");
46                 return PTR_ERR(root);
47         }
48
49         path = btrfs_alloc_path();
50         if (!path) {
51                 test_msg("Could not allocate path\n");
52                 kfree(root);
53                 return -ENOMEM;
54         }
55
56         path->nodes[0] = eb = alloc_dummy_extent_buffer(NULL, 4096);
57         if (!eb) {
58                 test_msg("Could not allocate dummy buffer\n");
59                 ret = -ENOMEM;
60                 goto out;
61         }
62         path->slots[0] = 0;
63
64         key.objectid = 0;
65         key.type = BTRFS_EXTENT_CSUM_KEY;
66         key.offset = 0;
67
68         setup_items_for_insert(root, path, &key, &value_len, value_len,
69                                value_len + sizeof(struct btrfs_item), 1);
70         item = btrfs_item_nr(0);
71         write_extent_buffer(eb, value, btrfs_item_ptr_offset(eb, 0),
72                             value_len);
73
74         key.offset = 3;
75
76         /*
77          * Passing NULL trans here should be safe because we have plenty of
78          * space in this leaf to split the item without having to split the
79          * leaf.
80          */
81         ret = btrfs_split_item(NULL, root, path, &key, 17);
82         if (ret) {
83                 test_msg("Split item failed %d\n", ret);
84                 goto out;
85         }
86
87         /*
88          * Read the first slot, it should have the original key and contain only
89          * 'mary had a little'
90          */
91         btrfs_item_key_to_cpu(eb, &key, 0);
92         if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY ||
93             key.offset != 0) {
94                 test_msg("Invalid key at slot 0\n");
95                 ret = -EINVAL;
96                 goto out;
97         }
98
99         item = btrfs_item_nr(0);
100         if (btrfs_item_size(eb, item) != strlen(split1)) {
101                 test_msg("Invalid len in the first split\n");
102                 ret = -EINVAL;
103                 goto out;
104         }
105
106         read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 0),
107                            strlen(split1));
108         if (memcmp(buf, split1, strlen(split1))) {
109                 test_msg("Data in the buffer doesn't match what it should "
110                          "in the first split have='%.*s' want '%s'\n",
111                          (int)strlen(split1), buf, split1);
112                 ret = -EINVAL;
113                 goto out;
114         }
115
116         btrfs_item_key_to_cpu(eb, &key, 1);
117         if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY ||
118             key.offset != 3) {
119                 test_msg("Invalid key at slot 1\n");
120                 ret = -EINVAL;
121                 goto out;
122         }
123
124         item = btrfs_item_nr(1);
125         if (btrfs_item_size(eb, item) != strlen(split2)) {
126                 test_msg("Invalid len in the second split\n");
127                 ret = -EINVAL;
128                 goto out;
129         }
130
131         read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 1),
132                            strlen(split2));
133         if (memcmp(buf, split2, strlen(split2))) {
134                 test_msg("Data in the buffer doesn't match what it should "
135                          "in the second split\n");
136                 ret = -EINVAL;
137                 goto out;
138         }
139
140         key.offset = 1;
141         /* Do it again so we test memmoving the other items in the leaf */
142         ret = btrfs_split_item(NULL, root, path, &key, 4);
143         if (ret) {
144                 test_msg("Second split item failed %d\n", ret);
145                 goto out;
146         }
147
148         btrfs_item_key_to_cpu(eb, &key, 0);
149         if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY ||
150             key.offset != 0) {
151                 test_msg("Invalid key at slot 0\n");
152                 ret = -EINVAL;
153                 goto out;
154         }
155
156         item = btrfs_item_nr(0);
157         if (btrfs_item_size(eb, item) != strlen(split3)) {
158                 test_msg("Invalid len in the first split\n");
159                 ret = -EINVAL;
160                 goto out;
161         }
162
163         read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 0),
164                            strlen(split3));
165         if (memcmp(buf, split3, strlen(split3))) {
166                 test_msg("Data in the buffer doesn't match what it should "
167                          "in the third split");
168                 ret = -EINVAL;
169                 goto out;
170         }
171
172         btrfs_item_key_to_cpu(eb, &key, 1);
173         if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY ||
174             key.offset != 1) {
175                 test_msg("Invalid key at slot 1\n");
176                 ret = -EINVAL;
177                 goto out;
178         }
179
180         item = btrfs_item_nr(1);
181         if (btrfs_item_size(eb, item) != strlen(split4)) {
182                 test_msg("Invalid len in the second split\n");
183                 ret = -EINVAL;
184                 goto out;
185         }
186
187         read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 1),
188                            strlen(split4));
189         if (memcmp(buf, split4, strlen(split4))) {
190                 test_msg("Data in the buffer doesn't match what it should "
191                          "in the fourth split\n");
192                 ret = -EINVAL;
193                 goto out;
194         }
195
196         btrfs_item_key_to_cpu(eb, &key, 2);
197         if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY ||
198             key.offset != 3) {
199                 test_msg("Invalid key at slot 2\n");
200                 ret = -EINVAL;
201                 goto out;
202         }
203
204         item = btrfs_item_nr(2);
205         if (btrfs_item_size(eb, item) != strlen(split2)) {
206                 test_msg("Invalid len in the second split\n");
207                 ret = -EINVAL;
208                 goto out;
209         }
210
211         read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 2),
212                            strlen(split2));
213         if (memcmp(buf, split2, strlen(split2))) {
214                 test_msg("Data in the buffer doesn't match what it should "
215                          "in the last chunk\n");
216                 ret = -EINVAL;
217                 goto out;
218         }
219 out:
220         btrfs_free_path(path);
221         kfree(root);
222         return ret;
223 }
224
225 int btrfs_test_extent_buffer_operations(void)
226 {
227         test_msg("Running extent buffer operation tests");
228         return test_btrfs_split_item();
229 }