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