inode-tests.c 31 KB

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