8a25fe8b7c452e78d823da897068748ae280de32
[sfrench/cifs-2.6.git] / fs / btrfs / tests / inode-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 "btrfs-tests.h"
20 #include "../ctree.h"
21 #include "../btrfs_inode.h"
22 #include "../disk-io.h"
23 #include "../extent_io.h"
24 #include "../volumes.h"
25 #include "../compression.h"
26
27 static void insert_extent(struct btrfs_root *root, u64 start, u64 len,
28                           u64 ram_bytes, u64 offset, u64 disk_bytenr,
29                           u64 disk_len, u32 type, u8 compression, int slot)
30 {
31         struct btrfs_path path;
32         struct btrfs_file_extent_item *fi;
33         struct extent_buffer *leaf = root->node;
34         struct btrfs_key key;
35         u32 value_len = sizeof(struct btrfs_file_extent_item);
36
37         if (type == BTRFS_FILE_EXTENT_INLINE)
38                 value_len += len;
39         memset(&path, 0, sizeof(path));
40
41         path.nodes[0] = leaf;
42         path.slots[0] = slot;
43
44         key.objectid = BTRFS_FIRST_FREE_OBJECTID;
45         key.type = BTRFS_EXTENT_DATA_KEY;
46         key.offset = start;
47
48         setup_items_for_insert(root, &path, &key, &value_len, value_len,
49                                value_len + sizeof(struct btrfs_item), 1);
50         fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
51         btrfs_set_file_extent_generation(leaf, fi, 1);
52         btrfs_set_file_extent_type(leaf, fi, type);
53         btrfs_set_file_extent_disk_bytenr(leaf, fi, disk_bytenr);
54         btrfs_set_file_extent_disk_num_bytes(leaf, fi, disk_len);
55         btrfs_set_file_extent_offset(leaf, fi, offset);
56         btrfs_set_file_extent_num_bytes(leaf, fi, len);
57         btrfs_set_file_extent_ram_bytes(leaf, fi, ram_bytes);
58         btrfs_set_file_extent_compression(leaf, fi, compression);
59         btrfs_set_file_extent_encryption(leaf, fi, 0);
60         btrfs_set_file_extent_other_encoding(leaf, fi, 0);
61 }
62
63 static void insert_inode_item_key(struct btrfs_root *root)
64 {
65         struct btrfs_path path;
66         struct extent_buffer *leaf = root->node;
67         struct btrfs_key key;
68         u32 value_len = 0;
69
70         memset(&path, 0, sizeof(path));
71
72         path.nodes[0] = leaf;
73         path.slots[0] = 0;
74
75         key.objectid = BTRFS_INODE_ITEM_KEY;
76         key.type = BTRFS_INODE_ITEM_KEY;
77         key.offset = 0;
78
79         setup_items_for_insert(root, &path, &key, &value_len, value_len,
80                                value_len + sizeof(struct btrfs_item), 1);
81 }
82
83 /*
84  * Build the most complicated map of extents the earth has ever seen.  We want
85  * this so we can test all of the corner cases of btrfs_get_extent.  Here is a
86  * diagram of how the extents will look though this may not be possible we still
87  * want to make sure everything acts normally (the last number is not inclusive)
88  *
89  * [0 - 5][5 -  6][6 - 10][10 - 4096][  4096 - 8192 ][8192 - 12288]
90  * [hole ][inline][ hole ][ regular ][regular1 split][    hole    ]
91  *
92  * [ 12288 - 20480][20480 - 24576][  24576 - 28672  ][28672 - 36864][36864 - 45056]
93  * [regular1 split][   prealloc1 ][prealloc1 written][   prealloc1 ][ compressed  ]
94  *
95  * [45056 - 49152][49152-53248][53248-61440][61440-65536][     65536+81920   ]
96  * [ compressed1 ][  regular  ][compressed1][  regular  ][ hole but no extent]
97  *
98  * [81920-86016]
99  * [  regular  ]
100  */
101 static void setup_file_extents(struct btrfs_root *root)
102 {
103         int slot = 0;
104         u64 disk_bytenr = SZ_1M;
105         u64 offset = 0;
106
107         /* First we want a hole */
108         insert_extent(root, offset, 5, 5, 0, 0, 0, BTRFS_FILE_EXTENT_REG, 0,
109                       slot);
110         slot++;
111         offset += 5;
112
113         /*
114          * Now we want an inline extent, I don't think this is possible but hey
115          * why not?  Also keep in mind if we have an inline extent it counts as
116          * the whole first page.  If we were to expand it we would have to cow
117          * and we wouldn't have an inline extent anymore.
118          */
119         insert_extent(root, offset, 1, 1, 0, 0, 0, BTRFS_FILE_EXTENT_INLINE, 0,
120                       slot);
121         slot++;
122         offset = 4096;
123
124         /* Now another hole */
125         insert_extent(root, offset, 4, 4, 0, 0, 0, BTRFS_FILE_EXTENT_REG, 0,
126                       slot);
127         slot++;
128         offset += 4;
129
130         /* Now for a regular extent */
131         insert_extent(root, offset, 4095, 4095, 0, disk_bytenr, 4096,
132                       BTRFS_FILE_EXTENT_REG, 0, slot);
133         slot++;
134         disk_bytenr += 4096;
135         offset += 4095;
136
137         /*
138          * Now for 3 extents that were split from a hole punch so we test
139          * offsets properly.
140          */
141         insert_extent(root, offset, 4096, 16384, 0, disk_bytenr, 16384,
142                       BTRFS_FILE_EXTENT_REG, 0, slot);
143         slot++;
144         offset += 4096;
145         insert_extent(root, offset, 4096, 4096, 0, 0, 0, BTRFS_FILE_EXTENT_REG,
146                       0, slot);
147         slot++;
148         offset += 4096;
149         insert_extent(root, offset, 8192, 16384, 8192, disk_bytenr, 16384,
150                       BTRFS_FILE_EXTENT_REG, 0, slot);
151         slot++;
152         offset += 8192;
153         disk_bytenr += 16384;
154
155         /* Now for a unwritten prealloc extent */
156         insert_extent(root, offset, 4096, 4096, 0, disk_bytenr, 4096,
157                       BTRFS_FILE_EXTENT_PREALLOC, 0, slot);
158         slot++;
159         offset += 4096;
160
161         /*
162          * We want to jack up disk_bytenr a little more so the em stuff doesn't
163          * merge our records.
164          */
165         disk_bytenr += 8192;
166
167         /*
168          * Now for a partially written prealloc extent, basically the same as
169          * the hole punch example above.  Ram_bytes never changes when you mark
170          * extents written btw.
171          */
172         insert_extent(root, offset, 4096, 16384, 0, disk_bytenr, 16384,
173                       BTRFS_FILE_EXTENT_PREALLOC, 0, slot);
174         slot++;
175         offset += 4096;
176         insert_extent(root, offset, 4096, 16384, 4096, disk_bytenr, 16384,
177                       BTRFS_FILE_EXTENT_REG, 0, slot);
178         slot++;
179         offset += 4096;
180         insert_extent(root, offset, 8192, 16384, 8192, disk_bytenr, 16384,
181                       BTRFS_FILE_EXTENT_PREALLOC, 0, slot);
182         slot++;
183         offset += 8192;
184         disk_bytenr += 16384;
185
186         /* Now a normal compressed extent */
187         insert_extent(root, offset, 8192, 8192, 0, disk_bytenr, 4096,
188                       BTRFS_FILE_EXTENT_REG, BTRFS_COMPRESS_ZLIB, slot);
189         slot++;
190         offset += 8192;
191         /* No merges */
192         disk_bytenr += 8192;
193
194         /* Now a split compressed extent */
195         insert_extent(root, offset, 4096, 16384, 0, disk_bytenr, 4096,
196                       BTRFS_FILE_EXTENT_REG, BTRFS_COMPRESS_ZLIB, slot);
197         slot++;
198         offset += 4096;
199         insert_extent(root, offset, 4096, 4096, 0, disk_bytenr + 4096, 4096,
200                       BTRFS_FILE_EXTENT_REG, 0, slot);
201         slot++;
202         offset += 4096;
203         insert_extent(root, offset, 8192, 16384, 8192, disk_bytenr, 4096,
204                       BTRFS_FILE_EXTENT_REG, BTRFS_COMPRESS_ZLIB, slot);
205         slot++;
206         offset += 8192;
207         disk_bytenr += 8192;
208
209         /* Now extents that have a hole but no hole extent */
210         insert_extent(root, offset, 4096, 4096, 0, disk_bytenr, 4096,
211                       BTRFS_FILE_EXTENT_REG, 0, slot);
212         slot++;
213         offset += 16384;
214         disk_bytenr += 4096;
215         insert_extent(root, offset, 4096, 4096, 0, disk_bytenr, 4096,
216                       BTRFS_FILE_EXTENT_REG, 0, slot);
217 }
218
219 static unsigned long prealloc_only = 0;
220 static unsigned long compressed_only = 0;
221 static unsigned long vacancy_only = 0;
222
223 static noinline int test_btrfs_get_extent(void)
224 {
225         struct inode *inode = NULL;
226         struct btrfs_root *root = NULL;
227         struct extent_map *em = NULL;
228         u64 orig_start;
229         u64 disk_bytenr;
230         u64 offset;
231         int ret = -ENOMEM;
232
233         inode = btrfs_new_test_inode();
234         if (!inode) {
235                 test_msg("Couldn't allocate inode\n");
236                 return ret;
237         }
238
239         BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY;
240         BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID;
241         BTRFS_I(inode)->location.offset = 0;
242
243         root = btrfs_alloc_dummy_root();
244         if (IS_ERR(root)) {
245                 test_msg("Couldn't allocate root\n");
246                 goto out;
247         }
248
249         /*
250          * We do this since btrfs_get_extent wants to assign em->bdev to
251          * root->fs_info->fs_devices->latest_bdev.
252          */
253         root->fs_info = btrfs_alloc_dummy_fs_info();
254         if (!root->fs_info) {
255                 test_msg("Couldn't allocate dummy fs info\n");
256                 goto out;
257         }
258
259         root->node = alloc_dummy_extent_buffer(NULL, 4096);
260         if (!root->node) {
261                 test_msg("Couldn't allocate dummy buffer\n");
262                 goto out;
263         }
264
265         /*
266          * We will just free a dummy node if it's ref count is 2 so we need an
267          * extra ref so our searches don't accidentally release our page.
268          */
269         extent_buffer_get(root->node);
270         btrfs_set_header_nritems(root->node, 0);
271         btrfs_set_header_level(root->node, 0);
272         ret = -EINVAL;
273
274         /* First with no extents */
275         BTRFS_I(inode)->root = root;
276         em = btrfs_get_extent(inode, NULL, 0, 0, 4096, 0);
277         if (IS_ERR(em)) {
278                 em = NULL;
279                 test_msg("Got an error when we shouldn't have\n");
280                 goto out;
281         }
282         if (em->block_start != EXTENT_MAP_HOLE) {
283                 test_msg("Expected a hole, got %llu\n", em->block_start);
284                 goto out;
285         }
286         if (!test_bit(EXTENT_FLAG_VACANCY, &em->flags)) {
287                 test_msg("Vacancy flag wasn't set properly\n");
288                 goto out;
289         }
290         free_extent_map(em);
291         btrfs_drop_extent_cache(inode, 0, (u64)-1, 0);
292
293         /*
294          * All of the magic numbers are based on the mapping setup in
295          * setup_file_extents, so if you change anything there you need to
296          * update the comment and update the expected values below.
297          */
298         setup_file_extents(root);
299
300         em = btrfs_get_extent(inode, NULL, 0, 0, (u64)-1, 0);
301         if (IS_ERR(em)) {
302                 test_msg("Got an error when we shouldn't have\n");
303                 goto out;
304         }
305         if (em->block_start != EXTENT_MAP_HOLE) {
306                 test_msg("Expected a hole, got %llu\n", em->block_start);
307                 goto out;
308         }
309         if (em->start != 0 || em->len != 5) {
310                 test_msg("Unexpected extent wanted start 0 len 5, got start "
311                          "%llu len %llu\n", em->start, em->len);
312                 goto out;
313         }
314         if (em->flags != 0) {
315                 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
316                 goto out;
317         }
318         offset = em->start + em->len;
319         free_extent_map(em);
320
321         em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
322         if (IS_ERR(em)) {
323                 test_msg("Got an error when we shouldn't have\n");
324                 goto out;
325         }
326         if (em->block_start != EXTENT_MAP_INLINE) {
327                 test_msg("Expected an inline, got %llu\n", em->block_start);
328                 goto out;
329         }
330         if (em->start != offset || em->len != 4091) {
331                 test_msg("Unexpected extent wanted start %llu len 1, got start "
332                          "%llu len %llu\n", offset, em->start, em->len);
333                 goto out;
334         }
335         if (em->flags != 0) {
336                 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
337                 goto out;
338         }
339         /*
340          * We don't test anything else for inline since it doesn't get set
341          * unless we have a page for it to write into.  Maybe we should change
342          * this?
343          */
344         offset = em->start + em->len;
345         free_extent_map(em);
346
347         em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
348         if (IS_ERR(em)) {
349                 test_msg("Got an error when we shouldn't have\n");
350                 goto out;
351         }
352         if (em->block_start != EXTENT_MAP_HOLE) {
353                 test_msg("Expected a hole, got %llu\n", em->block_start);
354                 goto out;
355         }
356         if (em->start != offset || em->len != 4) {
357                 test_msg("Unexpected extent wanted start %llu len 4, got start "
358                          "%llu len %llu\n", offset, em->start, em->len);
359                 goto out;
360         }
361         if (em->flags != 0) {
362                 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
363                 goto out;
364         }
365         offset = em->start + em->len;
366         free_extent_map(em);
367
368         /* Regular extent */
369         em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
370         if (IS_ERR(em)) {
371                 test_msg("Got an error when we shouldn't have\n");
372                 goto out;
373         }
374         if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
375                 test_msg("Expected a real extent, got %llu\n", em->block_start);
376                 goto out;
377         }
378         if (em->start != offset || em->len != 4095) {
379                 test_msg("Unexpected extent wanted start %llu len 4095, got "
380                          "start %llu len %llu\n", offset, em->start, em->len);
381                 goto out;
382         }
383         if (em->flags != 0) {
384                 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
385                 goto out;
386         }
387         if (em->orig_start != em->start) {
388                 test_msg("Wrong orig offset, want %llu, have %llu\n", em->start,
389                          em->orig_start);
390                 goto out;
391         }
392         offset = em->start + em->len;
393         free_extent_map(em);
394
395         /* The next 3 are split extents */
396         em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
397         if (IS_ERR(em)) {
398                 test_msg("Got an error when we shouldn't have\n");
399                 goto out;
400         }
401         if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
402                 test_msg("Expected a real extent, got %llu\n", em->block_start);
403                 goto out;
404         }
405         if (em->start != offset || em->len != 4096) {
406                 test_msg("Unexpected extent wanted start %llu len 4096, got "
407                          "start %llu len %llu\n", offset, em->start, em->len);
408                 goto out;
409         }
410         if (em->flags != 0) {
411                 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
412                 goto out;
413         }
414         if (em->orig_start != em->start) {
415                 test_msg("Wrong orig offset, want %llu, have %llu\n", em->start,
416                          em->orig_start);
417                 goto out;
418         }
419         disk_bytenr = em->block_start;
420         orig_start = em->start;
421         offset = em->start + em->len;
422         free_extent_map(em);
423
424         em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
425         if (IS_ERR(em)) {
426                 test_msg("Got an error when we shouldn't have\n");
427                 goto out;
428         }
429         if (em->block_start != EXTENT_MAP_HOLE) {
430                 test_msg("Expected a hole, got %llu\n", em->block_start);
431                 goto out;
432         }
433         if (em->start != offset || em->len != 4096) {
434                 test_msg("Unexpected extent wanted start %llu len 4096, got "
435                          "start %llu len %llu\n", offset, em->start, em->len);
436                 goto out;
437         }
438         if (em->flags != 0) {
439                 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
440                 goto out;
441         }
442         offset = em->start + em->len;
443         free_extent_map(em);
444
445         em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
446         if (IS_ERR(em)) {
447                 test_msg("Got an error when we shouldn't have\n");
448                 goto out;
449         }
450         if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
451                 test_msg("Expected a real extent, got %llu\n", em->block_start);
452                 goto out;
453         }
454         if (em->start != offset || em->len != 8192) {
455                 test_msg("Unexpected extent wanted start %llu len 8192, got "
456                          "start %llu len %llu\n", offset, em->start, em->len);
457                 goto out;
458         }
459         if (em->flags != 0) {
460                 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
461                 goto out;
462         }
463         if (em->orig_start != orig_start) {
464                 test_msg("Wrong orig offset, want %llu, have %llu\n",
465                          orig_start, em->orig_start);
466                 goto out;
467         }
468         disk_bytenr += (em->start - orig_start);
469         if (em->block_start != disk_bytenr) {
470                 test_msg("Wrong block start, want %llu, have %llu\n",
471                          disk_bytenr, em->block_start);
472                 goto out;
473         }
474         offset = em->start + em->len;
475         free_extent_map(em);
476
477         /* Prealloc extent */
478         em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
479         if (IS_ERR(em)) {
480                 test_msg("Got an error when we shouldn't have\n");
481                 goto out;
482         }
483         if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
484                 test_msg("Expected a real extent, got %llu\n", em->block_start);
485                 goto out;
486         }
487         if (em->start != offset || em->len != 4096) {
488                 test_msg("Unexpected extent wanted start %llu len 4096, got "
489                          "start %llu len %llu\n", offset, em->start, em->len);
490                 goto out;
491         }
492         if (em->flags != prealloc_only) {
493                 test_msg("Unexpected flags set, want %lu have %lu\n",
494                          prealloc_only, em->flags);
495                 goto out;
496         }
497         if (em->orig_start != em->start) {
498                 test_msg("Wrong orig offset, want %llu, have %llu\n", em->start,
499                          em->orig_start);
500                 goto out;
501         }
502         offset = em->start + em->len;
503         free_extent_map(em);
504
505         /* The next 3 are a half written prealloc extent */
506         em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
507         if (IS_ERR(em)) {
508                 test_msg("Got an error when we shouldn't have\n");
509                 goto out;
510         }
511         if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
512                 test_msg("Expected a real extent, got %llu\n", em->block_start);
513                 goto out;
514         }
515         if (em->start != offset || em->len != 4096) {
516                 test_msg("Unexpected extent wanted start %llu len 4096, got "
517                          "start %llu len %llu\n", offset, em->start, em->len);
518                 goto out;
519         }
520         if (em->flags != prealloc_only) {
521                 test_msg("Unexpected flags set, want %lu have %lu\n",
522                          prealloc_only, em->flags);
523                 goto out;
524         }
525         if (em->orig_start != em->start) {
526                 test_msg("Wrong orig offset, want %llu, have %llu\n", em->start,
527                          em->orig_start);
528                 goto out;
529         }
530         disk_bytenr = em->block_start;
531         orig_start = em->start;
532         offset = em->start + em->len;
533         free_extent_map(em);
534
535         em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
536         if (IS_ERR(em)) {
537                 test_msg("Got an error when we shouldn't have\n");
538                 goto out;
539         }
540         if (em->block_start >= EXTENT_MAP_HOLE) {
541                 test_msg("Expected a real extent, got %llu\n", em->block_start);
542                 goto out;
543         }
544         if (em->start != offset || em->len != 4096) {
545                 test_msg("Unexpected extent wanted start %llu len 4096, got "
546                          "start %llu len %llu\n", offset, em->start, em->len);
547                 goto out;
548         }
549         if (em->flags != 0) {
550                 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
551                 goto out;
552         }
553         if (em->orig_start != orig_start) {
554                 test_msg("Unexpected orig offset, wanted %llu, have %llu\n",
555                          orig_start, em->orig_start);
556                 goto out;
557         }
558         if (em->block_start != (disk_bytenr + (em->start - em->orig_start))) {
559                 test_msg("Unexpected block start, wanted %llu, have %llu\n",
560                          disk_bytenr + (em->start - em->orig_start),
561                          em->block_start);
562                 goto out;
563         }
564         offset = em->start + em->len;
565         free_extent_map(em);
566
567         em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
568         if (IS_ERR(em)) {
569                 test_msg("Got an error when we shouldn't have\n");
570                 goto out;
571         }
572         if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
573                 test_msg("Expected a real extent, got %llu\n", em->block_start);
574                 goto out;
575         }
576         if (em->start != offset || em->len != 8192) {
577                 test_msg("Unexpected extent wanted start %llu len 8192, got "
578                          "start %llu len %llu\n", offset, em->start, em->len);
579                 goto out;
580         }
581         if (em->flags != prealloc_only) {
582                 test_msg("Unexpected flags set, want %lu have %lu\n",
583                          prealloc_only, em->flags);
584                 goto out;
585         }
586         if (em->orig_start != orig_start) {
587                 test_msg("Wrong orig offset, want %llu, have %llu\n", orig_start,
588                          em->orig_start);
589                 goto out;
590         }
591         if (em->block_start != (disk_bytenr + (em->start - em->orig_start))) {
592                 test_msg("Unexpected block start, wanted %llu, have %llu\n",
593                          disk_bytenr + (em->start - em->orig_start),
594                          em->block_start);
595                 goto out;
596         }
597         offset = em->start + em->len;
598         free_extent_map(em);
599
600         /* Now for the compressed extent */
601         em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
602         if (IS_ERR(em)) {
603                 test_msg("Got an error when we shouldn't have\n");
604                 goto out;
605         }
606         if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
607                 test_msg("Expected a real extent, got %llu\n", em->block_start);
608                 goto out;
609         }
610         if (em->start != offset || em->len != 8192) {
611                 test_msg("Unexpected extent wanted start %llu len 8192, got "
612                          "start %llu len %llu\n", offset, em->start, em->len);
613                 goto out;
614         }
615         if (em->flags != compressed_only) {
616                 test_msg("Unexpected flags set, want %lu have %lu\n",
617                          compressed_only, em->flags);
618                 goto out;
619         }
620         if (em->orig_start != em->start) {
621                 test_msg("Wrong orig offset, want %llu, have %llu\n",
622                          em->start, em->orig_start);
623                 goto out;
624         }
625         if (em->compress_type != BTRFS_COMPRESS_ZLIB) {
626                 test_msg("Unexpected compress type, wanted %d, got %d\n",
627                          BTRFS_COMPRESS_ZLIB, em->compress_type);
628                 goto out;
629         }
630         offset = em->start + em->len;
631         free_extent_map(em);
632
633         /* Split compressed extent */
634         em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
635         if (IS_ERR(em)) {
636                 test_msg("Got an error when we shouldn't have\n");
637                 goto out;
638         }
639         if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
640                 test_msg("Expected a real extent, got %llu\n", em->block_start);
641                 goto out;
642         }
643         if (em->start != offset || em->len != 4096) {
644                 test_msg("Unexpected extent wanted start %llu len 4096, got "
645                          "start %llu len %llu\n", offset, em->start, em->len);
646                 goto out;
647         }
648         if (em->flags != compressed_only) {
649                 test_msg("Unexpected flags set, want %lu have %lu\n",
650                          compressed_only, em->flags);
651                 goto out;
652         }
653         if (em->orig_start != em->start) {
654                 test_msg("Wrong orig offset, want %llu, have %llu\n",
655                          em->start, em->orig_start);
656                 goto out;
657         }
658         if (em->compress_type != BTRFS_COMPRESS_ZLIB) {
659                 test_msg("Unexpected compress type, wanted %d, got %d\n",
660                          BTRFS_COMPRESS_ZLIB, em->compress_type);
661                 goto out;
662         }
663         disk_bytenr = em->block_start;
664         orig_start = em->start;
665         offset = em->start + em->len;
666         free_extent_map(em);
667
668         em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
669         if (IS_ERR(em)) {
670                 test_msg("Got an error when we shouldn't have\n");
671                 goto out;
672         }
673         if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
674                 test_msg("Expected a real extent, got %llu\n", em->block_start);
675                 goto out;
676         }
677         if (em->start != offset || em->len != 4096) {
678                 test_msg("Unexpected extent wanted start %llu len 4096, got "
679                          "start %llu len %llu\n", offset, em->start, em->len);
680                 goto out;
681         }
682         if (em->flags != 0) {
683                 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
684                 goto out;
685         }
686         if (em->orig_start != em->start) {
687                 test_msg("Wrong orig offset, want %llu, have %llu\n", em->start,
688                          em->orig_start);
689                 goto out;
690         }
691         offset = em->start + em->len;
692         free_extent_map(em);
693
694         em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
695         if (IS_ERR(em)) {
696                 test_msg("Got an error when we shouldn't have\n");
697                 goto out;
698         }
699         if (em->block_start != disk_bytenr) {
700                 test_msg("Block start does not match, want %llu got %llu\n",
701                          disk_bytenr, em->block_start);
702                 goto out;
703         }
704         if (em->start != offset || em->len != 8192) {
705                 test_msg("Unexpected extent wanted start %llu len 8192, got "
706                          "start %llu len %llu\n", offset, em->start, em->len);
707                 goto out;
708         }
709         if (em->flags != compressed_only) {
710                 test_msg("Unexpected flags set, want %lu have %lu\n",
711                          compressed_only, em->flags);
712                 goto out;
713         }
714         if (em->orig_start != orig_start) {
715                 test_msg("Wrong orig offset, want %llu, have %llu\n",
716                          em->start, orig_start);
717                 goto out;
718         }
719         if (em->compress_type != BTRFS_COMPRESS_ZLIB) {
720                 test_msg("Unexpected compress type, wanted %d, got %d\n",
721                          BTRFS_COMPRESS_ZLIB, em->compress_type);
722                 goto out;
723         }
724         offset = em->start + em->len;
725         free_extent_map(em);
726
727         /* A hole between regular extents but no hole extent */
728         em = btrfs_get_extent(inode, NULL, 0, offset + 6, 4096, 0);
729         if (IS_ERR(em)) {
730                 test_msg("Got an error when we shouldn't have\n");
731                 goto out;
732         }
733         if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
734                 test_msg("Expected a real extent, got %llu\n", em->block_start);
735                 goto out;
736         }
737         if (em->start != offset || em->len != 4096) {
738                 test_msg("Unexpected extent wanted start %llu len 4096, got "
739                          "start %llu len %llu\n", offset, em->start, em->len);
740                 goto out;
741         }
742         if (em->flags != 0) {
743                 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
744                 goto out;
745         }
746         if (em->orig_start != em->start) {
747                 test_msg("Wrong orig offset, want %llu, have %llu\n", em->start,
748                          em->orig_start);
749                 goto out;
750         }
751         offset = em->start + em->len;
752         free_extent_map(em);
753
754         em = btrfs_get_extent(inode, NULL, 0, offset, 4096 * 1024, 0);
755         if (IS_ERR(em)) {
756                 test_msg("Got an error when we shouldn't have\n");
757                 goto out;
758         }
759         if (em->block_start != EXTENT_MAP_HOLE) {
760                 test_msg("Expected a hole extent, got %llu\n", em->block_start);
761                 goto out;
762         }
763         /*
764          * Currently we just return a length that we requested rather than the
765          * length of the actual hole, if this changes we'll have to change this
766          * test.
767          */
768         if (em->start != offset || em->len != 12288) {
769                 test_msg("Unexpected extent wanted start %llu len 12288, got "
770                          "start %llu len %llu\n", offset, em->start, em->len);
771                 goto out;
772         }
773         if (em->flags != vacancy_only) {
774                 test_msg("Unexpected flags set, want %lu have %lu\n",
775                          vacancy_only, em->flags);
776                 goto out;
777         }
778         if (em->orig_start != em->start) {
779                 test_msg("Wrong orig offset, want %llu, have %llu\n", em->start,
780                          em->orig_start);
781                 goto out;
782         }
783         offset = em->start + em->len;
784         free_extent_map(em);
785
786         em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
787         if (IS_ERR(em)) {
788                 test_msg("Got an error when we shouldn't have\n");
789                 goto out;
790         }
791         if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
792                 test_msg("Expected a real extent, got %llu\n", em->block_start);
793                 goto out;
794         }
795         if (em->start != offset || em->len != 4096) {
796                 test_msg("Unexpected extent wanted start %llu len 4096, got "
797                          "start %llu len %llu\n", offset, em->start, em->len);
798                 goto out;
799         }
800         if (em->flags != 0) {
801                 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
802                 goto out;
803         }
804         if (em->orig_start != em->start) {
805                 test_msg("Wrong orig offset, want %llu, have %llu\n", em->start,
806                          em->orig_start);
807                 goto out;
808         }
809         ret = 0;
810 out:
811         if (!IS_ERR(em))
812                 free_extent_map(em);
813         iput(inode);
814         btrfs_free_dummy_root(root);
815         return ret;
816 }
817
818 static int test_hole_first(void)
819 {
820         struct inode *inode = NULL;
821         struct btrfs_root *root = NULL;
822         struct extent_map *em = NULL;
823         int ret = -ENOMEM;
824
825         inode = btrfs_new_test_inode();
826         if (!inode) {
827                 test_msg("Couldn't allocate inode\n");
828                 return ret;
829         }
830
831         BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY;
832         BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID;
833         BTRFS_I(inode)->location.offset = 0;
834
835         root = btrfs_alloc_dummy_root();
836         if (IS_ERR(root)) {
837                 test_msg("Couldn't allocate root\n");
838                 goto out;
839         }
840
841         root->fs_info = btrfs_alloc_dummy_fs_info();
842         if (!root->fs_info) {
843                 test_msg("Couldn't allocate dummy fs info\n");
844                 goto out;
845         }
846
847         root->node = alloc_dummy_extent_buffer(NULL, 4096);
848         if (!root->node) {
849                 test_msg("Couldn't allocate dummy buffer\n");
850                 goto out;
851         }
852
853         extent_buffer_get(root->node);
854         btrfs_set_header_nritems(root->node, 0);
855         btrfs_set_header_level(root->node, 0);
856         BTRFS_I(inode)->root = root;
857         ret = -EINVAL;
858
859         /*
860          * Need a blank inode item here just so we don't confuse
861          * btrfs_get_extent.
862          */
863         insert_inode_item_key(root);
864         insert_extent(root, 4096, 4096, 4096, 0, 4096, 4096,
865                       BTRFS_FILE_EXTENT_REG, 0, 1);
866         em = btrfs_get_extent(inode, NULL, 0, 0, 8192, 0);
867         if (IS_ERR(em)) {
868                 test_msg("Got an error when we shouldn't have\n");
869                 goto out;
870         }
871         if (em->block_start != EXTENT_MAP_HOLE) {
872                 test_msg("Expected a hole, got %llu\n", em->block_start);
873                 goto out;
874         }
875         if (em->start != 0 || em->len != 4096) {
876                 test_msg("Unexpected extent wanted start 0 len 4096, got start "
877                          "%llu len %llu\n", em->start, em->len);
878                 goto out;
879         }
880         if (em->flags != vacancy_only) {
881                 test_msg("Wrong flags, wanted %lu, have %lu\n", vacancy_only,
882                          em->flags);
883                 goto out;
884         }
885         free_extent_map(em);
886
887         em = btrfs_get_extent(inode, NULL, 0, 4096, 8192, 0);
888         if (IS_ERR(em)) {
889                 test_msg("Got an error when we shouldn't have\n");
890                 goto out;
891         }
892         if (em->block_start != 4096) {
893                 test_msg("Expected a real extent, got %llu\n", em->block_start);
894                 goto out;
895         }
896         if (em->start != 4096 || em->len != 4096) {
897                 test_msg("Unexpected extent wanted start 4096 len 4096, got "
898                          "start %llu len %llu\n", em->start, em->len);
899                 goto out;
900         }
901         if (em->flags != 0) {
902                 test_msg("Unexpected flags set, wanted 0 got %lu\n",
903                          em->flags);
904                 goto out;
905         }
906         ret = 0;
907 out:
908         if (!IS_ERR(em))
909                 free_extent_map(em);
910         iput(inode);
911         btrfs_free_dummy_root(root);
912         return ret;
913 }
914
915 static int test_extent_accounting(void)
916 {
917         struct inode *inode = NULL;
918         struct btrfs_root *root = NULL;
919         int ret = -ENOMEM;
920
921         inode = btrfs_new_test_inode();
922         if (!inode) {
923                 test_msg("Couldn't allocate inode\n");
924                 return ret;
925         }
926
927         root = btrfs_alloc_dummy_root();
928         if (IS_ERR(root)) {
929                 test_msg("Couldn't allocate root\n");
930                 goto out;
931         }
932
933         root->fs_info = btrfs_alloc_dummy_fs_info();
934         if (!root->fs_info) {
935                 test_msg("Couldn't allocate dummy fs info\n");
936                 goto out;
937         }
938
939         BTRFS_I(inode)->root = root;
940         btrfs_test_inode_set_ops(inode);
941
942         /* [BTRFS_MAX_EXTENT_SIZE] */
943         BTRFS_I(inode)->outstanding_extents++;
944         ret = btrfs_set_extent_delalloc(inode, 0, BTRFS_MAX_EXTENT_SIZE - 1,
945                                         NULL);
946         if (ret) {
947                 test_msg("btrfs_set_extent_delalloc returned %d\n", ret);
948                 goto out;
949         }
950         if (BTRFS_I(inode)->outstanding_extents != 1) {
951                 ret = -EINVAL;
952                 test_msg("Miscount, wanted 1, got %u\n",
953                          BTRFS_I(inode)->outstanding_extents);
954                 goto out;
955         }
956
957         /* [BTRFS_MAX_EXTENT_SIZE][4k] */
958         BTRFS_I(inode)->outstanding_extents++;
959         ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE,
960                                         BTRFS_MAX_EXTENT_SIZE + 4095, NULL);
961         if (ret) {
962                 test_msg("btrfs_set_extent_delalloc returned %d\n", ret);
963                 goto out;
964         }
965         if (BTRFS_I(inode)->outstanding_extents != 2) {
966                 ret = -EINVAL;
967                 test_msg("Miscount, wanted 2, got %u\n",
968                          BTRFS_I(inode)->outstanding_extents);
969                 goto out;
970         }
971
972         /* [BTRFS_MAX_EXTENT_SIZE/2][4K HOLE][the rest] */
973         ret = clear_extent_bit(&BTRFS_I(inode)->io_tree,
974                                BTRFS_MAX_EXTENT_SIZE >> 1,
975                                (BTRFS_MAX_EXTENT_SIZE >> 1) + 4095,
976                                EXTENT_DELALLOC | EXTENT_DIRTY |
977                                EXTENT_UPTODATE | EXTENT_DO_ACCOUNTING, 0, 0,
978                                NULL, GFP_KERNEL);
979         if (ret) {
980                 test_msg("clear_extent_bit returned %d\n", ret);
981                 goto out;
982         }
983         if (BTRFS_I(inode)->outstanding_extents != 2) {
984                 ret = -EINVAL;
985                 test_msg("Miscount, wanted 2, got %u\n",
986                          BTRFS_I(inode)->outstanding_extents);
987                 goto out;
988         }
989
990         /* [BTRFS_MAX_EXTENT_SIZE][4K] */
991         BTRFS_I(inode)->outstanding_extents++;
992         ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE >> 1,
993                                         (BTRFS_MAX_EXTENT_SIZE >> 1) + 4095,
994                                         NULL);
995         if (ret) {
996                 test_msg("btrfs_set_extent_delalloc returned %d\n", ret);
997                 goto out;
998         }
999         if (BTRFS_I(inode)->outstanding_extents != 2) {
1000                 ret = -EINVAL;
1001                 test_msg("Miscount, wanted 2, got %u\n",
1002                          BTRFS_I(inode)->outstanding_extents);
1003                 goto out;
1004         }
1005
1006         /*
1007          * [BTRFS_MAX_EXTENT_SIZE+4K][4K HOLE][BTRFS_MAX_EXTENT_SIZE+4K]
1008          *
1009          * I'm artificially adding 2 to outstanding_extents because in the
1010          * buffered IO case we'd add things up as we go, but I don't feel like
1011          * doing that here, this isn't the interesting case we want to test.
1012          */
1013         BTRFS_I(inode)->outstanding_extents += 2;
1014         ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE + 8192,
1015                                         (BTRFS_MAX_EXTENT_SIZE << 1) + 12287,
1016                                         NULL);
1017         if (ret) {
1018                 test_msg("btrfs_set_extent_delalloc returned %d\n", ret);
1019                 goto out;
1020         }
1021         if (BTRFS_I(inode)->outstanding_extents != 4) {
1022                 ret = -EINVAL;
1023                 test_msg("Miscount, wanted 4, got %u\n",
1024                          BTRFS_I(inode)->outstanding_extents);
1025                 goto out;
1026         }
1027
1028         /* [BTRFS_MAX_EXTENT_SIZE+4k][4k][BTRFS_MAX_EXTENT_SIZE+4k] */
1029         BTRFS_I(inode)->outstanding_extents++;
1030         ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE+4096,
1031                                         BTRFS_MAX_EXTENT_SIZE+8191, NULL);
1032         if (ret) {
1033                 test_msg("btrfs_set_extent_delalloc returned %d\n", ret);
1034                 goto out;
1035         }
1036         if (BTRFS_I(inode)->outstanding_extents != 3) {
1037                 ret = -EINVAL;
1038                 test_msg("Miscount, wanted 3, got %u\n",
1039                          BTRFS_I(inode)->outstanding_extents);
1040                 goto out;
1041         }
1042
1043         /* [BTRFS_MAX_EXTENT_SIZE+4k][4K HOLE][BTRFS_MAX_EXTENT_SIZE+4k] */
1044         ret = clear_extent_bit(&BTRFS_I(inode)->io_tree,
1045                                BTRFS_MAX_EXTENT_SIZE+4096,
1046                                BTRFS_MAX_EXTENT_SIZE+8191,
1047                                EXTENT_DIRTY | EXTENT_DELALLOC |
1048                                EXTENT_DO_ACCOUNTING | EXTENT_UPTODATE, 0, 0,
1049                                NULL, GFP_KERNEL);
1050         if (ret) {
1051                 test_msg("clear_extent_bit returned %d\n", ret);
1052                 goto out;
1053         }
1054         if (BTRFS_I(inode)->outstanding_extents != 4) {
1055                 ret = -EINVAL;
1056                 test_msg("Miscount, wanted 4, got %u\n",
1057                          BTRFS_I(inode)->outstanding_extents);
1058                 goto out;
1059         }
1060
1061         /*
1062          * Refill the hole again just for good measure, because I thought it
1063          * might fail and I'd rather satisfy my paranoia at this point.
1064          */
1065         BTRFS_I(inode)->outstanding_extents++;
1066         ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE+4096,
1067                                         BTRFS_MAX_EXTENT_SIZE+8191, NULL);
1068         if (ret) {
1069                 test_msg("btrfs_set_extent_delalloc returned %d\n", ret);
1070                 goto out;
1071         }
1072         if (BTRFS_I(inode)->outstanding_extents != 3) {
1073                 ret = -EINVAL;
1074                 test_msg("Miscount, wanted 3, got %u\n",
1075                          BTRFS_I(inode)->outstanding_extents);
1076                 goto out;
1077         }
1078
1079         /* Empty */
1080         ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, (u64)-1,
1081                                EXTENT_DIRTY | EXTENT_DELALLOC |
1082                                EXTENT_DO_ACCOUNTING | EXTENT_UPTODATE, 0, 0,
1083                                NULL, GFP_KERNEL);
1084         if (ret) {
1085                 test_msg("clear_extent_bit returned %d\n", ret);
1086                 goto out;
1087         }
1088         if (BTRFS_I(inode)->outstanding_extents) {
1089                 ret = -EINVAL;
1090                 test_msg("Miscount, wanted 0, got %u\n",
1091                          BTRFS_I(inode)->outstanding_extents);
1092                 goto out;
1093         }
1094         ret = 0;
1095 out:
1096         if (ret)
1097                 clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, (u64)-1,
1098                                  EXTENT_DIRTY | EXTENT_DELALLOC |
1099                                  EXTENT_DO_ACCOUNTING | EXTENT_UPTODATE, 0, 0,
1100                                  NULL, GFP_KERNEL);
1101         iput(inode);
1102         btrfs_free_dummy_root(root);
1103         return ret;
1104 }
1105
1106 int btrfs_test_inodes(void)
1107 {
1108         int ret;
1109
1110         set_bit(EXTENT_FLAG_COMPRESSED, &compressed_only);
1111         set_bit(EXTENT_FLAG_VACANCY, &vacancy_only);
1112         set_bit(EXTENT_FLAG_PREALLOC, &prealloc_only);
1113
1114         test_msg("Running btrfs_get_extent tests\n");
1115         ret = test_btrfs_get_extent();
1116         if (ret)
1117                 return ret;
1118         test_msg("Running hole first btrfs_get_extent test\n");
1119         ret = test_hole_first();
1120         if (ret)
1121                 return ret;
1122         test_msg("Running outstanding_extents tests\n");
1123         return test_extent_accounting();
1124 }