extent-map-tests.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2017 Oracle. 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 "../volumes.h"
  10. #include "../disk-io.h"
  11. #include "../block-group.h"
  12. static int free_extent_map_tree(struct btrfs_inode *inode)
  13. {
  14. struct extent_map_tree *em_tree = &inode->extent_tree;
  15. struct extent_map *em;
  16. struct rb_node *node;
  17. int ret = 0;
  18. write_lock(&em_tree->lock);
  19. while (!RB_EMPTY_ROOT(&em_tree->root)) {
  20. node = rb_first(&em_tree->root);
  21. em = rb_entry(node, struct extent_map, rb_node);
  22. btrfs_remove_extent_mapping(inode, em);
  23. #ifdef CONFIG_BTRFS_DEBUG
  24. if (refcount_read(&em->refs) != 1) {
  25. ret = -EINVAL;
  26. test_err(
  27. "em leak: em (start %llu len %llu disk_bytenr %llu disk_num_bytes %llu offset %llu) refs %d",
  28. em->start, em->len, em->disk_bytenr,
  29. em->disk_num_bytes, em->offset,
  30. refcount_read(&em->refs));
  31. refcount_set(&em->refs, 1);
  32. }
  33. #endif
  34. btrfs_free_extent_map(em);
  35. }
  36. write_unlock(&em_tree->lock);
  37. return ret;
  38. }
  39. /*
  40. * Test scenario:
  41. *
  42. * Suppose that no extent map has been loaded into memory yet, there is a file
  43. * extent [0, 16K), followed by another file extent [16K, 20K), two dio reads
  44. * are entering btrfs_get_extent() concurrently, t1 is reading [8K, 16K), t2 is
  45. * reading [0, 8K)
  46. *
  47. * t1 t2
  48. * btrfs_get_extent() btrfs_get_extent()
  49. * -> lookup_extent_mapping() ->lookup_extent_mapping()
  50. * -> add_extent_mapping(0, 16K)
  51. * -> return em
  52. * ->add_extent_mapping(0, 16K)
  53. * -> #handle -EEXIST
  54. */
  55. static int test_case_1(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
  56. {
  57. struct extent_map_tree *em_tree = &inode->extent_tree;
  58. struct extent_map *em;
  59. u64 start = 0;
  60. u64 len = SZ_8K;
  61. int ret;
  62. int ret2;
  63. em = btrfs_alloc_extent_map();
  64. if (!em) {
  65. test_std_err(TEST_ALLOC_EXTENT_MAP);
  66. return -ENOMEM;
  67. }
  68. /* Add [0, 16K) */
  69. em->start = 0;
  70. em->len = SZ_16K;
  71. em->disk_bytenr = 0;
  72. em->disk_num_bytes = SZ_16K;
  73. em->ram_bytes = SZ_16K;
  74. write_lock(&em_tree->lock);
  75. ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
  76. write_unlock(&em_tree->lock);
  77. if (ret < 0) {
  78. test_err("cannot add extent range [0, 16K)");
  79. goto out;
  80. }
  81. btrfs_free_extent_map(em);
  82. /* Add [16K, 20K) following [0, 16K) */
  83. em = btrfs_alloc_extent_map();
  84. if (!em) {
  85. test_std_err(TEST_ALLOC_EXTENT_MAP);
  86. ret = -ENOMEM;
  87. goto out;
  88. }
  89. em->start = SZ_16K;
  90. em->len = SZ_4K;
  91. em->disk_bytenr = SZ_32K; /* avoid merging */
  92. em->disk_num_bytes = SZ_4K;
  93. em->ram_bytes = SZ_4K;
  94. write_lock(&em_tree->lock);
  95. ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
  96. write_unlock(&em_tree->lock);
  97. if (ret < 0) {
  98. test_err("cannot add extent range [16K, 20K)");
  99. goto out;
  100. }
  101. btrfs_free_extent_map(em);
  102. em = btrfs_alloc_extent_map();
  103. if (!em) {
  104. test_std_err(TEST_ALLOC_EXTENT_MAP);
  105. ret = -ENOMEM;
  106. goto out;
  107. }
  108. /* Add [0, 8K), should return [0, 16K) instead. */
  109. em->start = start;
  110. em->len = len;
  111. em->disk_bytenr = start;
  112. em->disk_num_bytes = len;
  113. em->ram_bytes = len;
  114. write_lock(&em_tree->lock);
  115. ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
  116. write_unlock(&em_tree->lock);
  117. if (ret) {
  118. test_err("case1 [%llu %llu]: ret %d", start, start + len, ret);
  119. goto out;
  120. }
  121. if (!em) {
  122. test_err("case1 [%llu %llu]: no extent map returned",
  123. start, start + len);
  124. ret = -ENOENT;
  125. goto out;
  126. }
  127. if (em->start != 0 || btrfs_extent_map_end(em) != SZ_16K ||
  128. em->disk_bytenr != 0 || em->disk_num_bytes != SZ_16K) {
  129. test_err(
  130. "case1 [%llu %llu]: ret %d return a wrong em (start %llu len %llu disk_bytenr %llu disk_num_bytes %llu",
  131. start, start + len, ret, em->start, em->len,
  132. em->disk_bytenr, em->disk_num_bytes);
  133. ret = -EINVAL;
  134. }
  135. btrfs_free_extent_map(em);
  136. out:
  137. ret2 = free_extent_map_tree(inode);
  138. if (ret == 0)
  139. ret = ret2;
  140. return ret;
  141. }
  142. /*
  143. * Test scenario:
  144. *
  145. * Reading the inline ending up with EEXIST, ie. read an inline
  146. * extent and discard page cache and read it again.
  147. */
  148. static int test_case_2(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
  149. {
  150. struct extent_map_tree *em_tree = &inode->extent_tree;
  151. struct extent_map *em;
  152. int ret;
  153. int ret2;
  154. em = btrfs_alloc_extent_map();
  155. if (!em) {
  156. test_std_err(TEST_ALLOC_EXTENT_MAP);
  157. return -ENOMEM;
  158. }
  159. /*
  160. * Add [0, 1K) which is inlined. And the extent map length must
  161. * be one block.
  162. */
  163. em->start = 0;
  164. em->len = SZ_4K;
  165. em->disk_bytenr = EXTENT_MAP_INLINE;
  166. em->disk_num_bytes = 0;
  167. em->ram_bytes = SZ_1K;
  168. write_lock(&em_tree->lock);
  169. ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
  170. write_unlock(&em_tree->lock);
  171. if (ret < 0) {
  172. test_err("cannot add extent range [0, 1K)");
  173. goto out;
  174. }
  175. btrfs_free_extent_map(em);
  176. /* Add [4K, 8K) following [0, 1K) */
  177. em = btrfs_alloc_extent_map();
  178. if (!em) {
  179. test_std_err(TEST_ALLOC_EXTENT_MAP);
  180. ret = -ENOMEM;
  181. goto out;
  182. }
  183. em->start = SZ_4K;
  184. em->len = SZ_4K;
  185. em->disk_bytenr = SZ_4K;
  186. em->disk_num_bytes = SZ_4K;
  187. em->ram_bytes = SZ_4K;
  188. write_lock(&em_tree->lock);
  189. ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
  190. write_unlock(&em_tree->lock);
  191. if (ret < 0) {
  192. test_err("cannot add extent range [4K, 8K)");
  193. goto out;
  194. }
  195. btrfs_free_extent_map(em);
  196. em = btrfs_alloc_extent_map();
  197. if (!em) {
  198. test_std_err(TEST_ALLOC_EXTENT_MAP);
  199. ret = -ENOMEM;
  200. goto out;
  201. }
  202. /* Add [0, 1K) */
  203. em->start = 0;
  204. em->len = SZ_4K;
  205. em->disk_bytenr = EXTENT_MAP_INLINE;
  206. em->disk_num_bytes = 0;
  207. em->ram_bytes = SZ_1K;
  208. write_lock(&em_tree->lock);
  209. ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
  210. write_unlock(&em_tree->lock);
  211. if (ret) {
  212. test_err("case2 [0 1K]: ret %d", ret);
  213. goto out;
  214. }
  215. if (!em) {
  216. test_err("case2 [0 1K]: no extent map returned");
  217. ret = -ENOENT;
  218. goto out;
  219. }
  220. if (em->start != 0 || btrfs_extent_map_end(em) != SZ_4K ||
  221. em->disk_bytenr != EXTENT_MAP_INLINE) {
  222. test_err(
  223. "case2 [0 1K]: ret %d return a wrong em (start %llu len %llu disk_bytenr %llu",
  224. ret, em->start, em->len, em->disk_bytenr);
  225. ret = -EINVAL;
  226. }
  227. btrfs_free_extent_map(em);
  228. out:
  229. ret2 = free_extent_map_tree(inode);
  230. if (ret == 0)
  231. ret = ret2;
  232. return ret;
  233. }
  234. static int __test_case_3(struct btrfs_fs_info *fs_info,
  235. struct btrfs_inode *inode, u64 start)
  236. {
  237. struct extent_map_tree *em_tree = &inode->extent_tree;
  238. struct extent_map *em;
  239. u64 len = SZ_4K;
  240. int ret;
  241. int ret2;
  242. em = btrfs_alloc_extent_map();
  243. if (!em) {
  244. test_std_err(TEST_ALLOC_EXTENT_MAP);
  245. return -ENOMEM;
  246. }
  247. /* Add [4K, 8K) */
  248. em->start = SZ_4K;
  249. em->len = SZ_4K;
  250. em->disk_bytenr = SZ_4K;
  251. em->disk_num_bytes = SZ_4K;
  252. em->ram_bytes = SZ_4K;
  253. write_lock(&em_tree->lock);
  254. ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
  255. write_unlock(&em_tree->lock);
  256. if (ret < 0) {
  257. test_err("cannot add extent range [4K, 8K)");
  258. goto out;
  259. }
  260. btrfs_free_extent_map(em);
  261. em = btrfs_alloc_extent_map();
  262. if (!em) {
  263. test_std_err(TEST_ALLOC_EXTENT_MAP);
  264. ret = -ENOMEM;
  265. goto out;
  266. }
  267. /* Add [0, 16K) */
  268. em->start = 0;
  269. em->len = SZ_16K;
  270. em->disk_bytenr = 0;
  271. em->disk_num_bytes = SZ_16K;
  272. em->ram_bytes = SZ_16K;
  273. write_lock(&em_tree->lock);
  274. ret = btrfs_add_extent_mapping(inode, &em, start, len);
  275. write_unlock(&em_tree->lock);
  276. if (ret) {
  277. test_err("case3 [%llu %llu): ret %d",
  278. start, start + len, ret);
  279. goto out;
  280. }
  281. if (!em) {
  282. test_err("case3 [%llu %llu): no extent map returned",
  283. start, start + len);
  284. ret = -ENOENT;
  285. goto out;
  286. }
  287. /*
  288. * Since bytes within em are contiguous, em->block_start is identical to
  289. * em->start.
  290. */
  291. if (start < em->start || start + len > btrfs_extent_map_end(em) ||
  292. em->start != btrfs_extent_map_block_start(em)) {
  293. test_err(
  294. "case3 [%llu %llu): ret %d em (start %llu len %llu disk_bytenr %llu block_len %llu)",
  295. start, start + len, ret, em->start, em->len,
  296. em->disk_bytenr, em->disk_num_bytes);
  297. ret = -EINVAL;
  298. }
  299. btrfs_free_extent_map(em);
  300. out:
  301. ret2 = free_extent_map_tree(inode);
  302. if (ret == 0)
  303. ret = ret2;
  304. return ret;
  305. }
  306. /*
  307. * Test scenario:
  308. *
  309. * Suppose that no extent map has been loaded into memory yet.
  310. * There is a file extent [0, 16K), two jobs are running concurrently
  311. * against it, t1 is buffered writing to [4K, 8K) and t2 is doing dio
  312. * read from [0, 4K) or [8K, 12K) or [12K, 16K).
  313. *
  314. * t1 goes ahead of t2 and adds em [4K, 8K) into tree.
  315. *
  316. * t1 t2
  317. * cow_file_range() btrfs_get_extent()
  318. * -> lookup_extent_mapping()
  319. * -> add_extent_mapping()
  320. * -> add_extent_mapping()
  321. */
  322. static int test_case_3(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
  323. {
  324. int ret;
  325. ret = __test_case_3(fs_info, inode, 0);
  326. if (ret)
  327. return ret;
  328. ret = __test_case_3(fs_info, inode, SZ_8K);
  329. if (ret)
  330. return ret;
  331. ret = __test_case_3(fs_info, inode, (12 * SZ_1K));
  332. return ret;
  333. }
  334. static int __test_case_4(struct btrfs_fs_info *fs_info,
  335. struct btrfs_inode *inode, u64 start)
  336. {
  337. struct extent_map_tree *em_tree = &inode->extent_tree;
  338. struct extent_map *em;
  339. u64 len = SZ_4K;
  340. int ret;
  341. int ret2;
  342. em = btrfs_alloc_extent_map();
  343. if (!em) {
  344. test_std_err(TEST_ALLOC_EXTENT_MAP);
  345. return -ENOMEM;
  346. }
  347. /* Add [0K, 8K) */
  348. em->start = 0;
  349. em->len = SZ_8K;
  350. em->disk_bytenr = 0;
  351. em->disk_num_bytes = SZ_8K;
  352. em->ram_bytes = SZ_8K;
  353. write_lock(&em_tree->lock);
  354. ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
  355. write_unlock(&em_tree->lock);
  356. if (ret < 0) {
  357. test_err("cannot add extent range [0, 8K)");
  358. goto out;
  359. }
  360. btrfs_free_extent_map(em);
  361. em = btrfs_alloc_extent_map();
  362. if (!em) {
  363. test_std_err(TEST_ALLOC_EXTENT_MAP);
  364. ret = -ENOMEM;
  365. goto out;
  366. }
  367. /* Add [8K, 32K) */
  368. em->start = SZ_8K;
  369. em->len = 24 * SZ_1K;
  370. em->disk_bytenr = SZ_16K; /* avoid merging */
  371. em->disk_num_bytes = 24 * SZ_1K;
  372. em->ram_bytes = 24 * SZ_1K;
  373. write_lock(&em_tree->lock);
  374. ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
  375. write_unlock(&em_tree->lock);
  376. if (ret < 0) {
  377. test_err("cannot add extent range [8K, 32K)");
  378. goto out;
  379. }
  380. btrfs_free_extent_map(em);
  381. em = btrfs_alloc_extent_map();
  382. if (!em) {
  383. test_std_err(TEST_ALLOC_EXTENT_MAP);
  384. ret = -ENOMEM;
  385. goto out;
  386. }
  387. /* Add [0K, 32K) */
  388. em->start = 0;
  389. em->len = SZ_32K;
  390. em->disk_bytenr = 0;
  391. em->disk_num_bytes = SZ_32K;
  392. em->ram_bytes = SZ_32K;
  393. write_lock(&em_tree->lock);
  394. ret = btrfs_add_extent_mapping(inode, &em, start, len);
  395. write_unlock(&em_tree->lock);
  396. if (ret) {
  397. test_err("case4 [%llu %llu): ret %d",
  398. start, start + len, ret);
  399. goto out;
  400. }
  401. if (!em) {
  402. test_err("case4 [%llu %llu): no extent map returned",
  403. start, start + len);
  404. ret = -ENOENT;
  405. goto out;
  406. }
  407. if (start < em->start || start + len > btrfs_extent_map_end(em)) {
  408. test_err(
  409. "case4 [%llu %llu): ret %d, added wrong em (start %llu len %llu disk_bytenr %llu disk_num_bytes %llu)",
  410. start, start + len, ret, em->start, em->len,
  411. em->disk_bytenr, em->disk_num_bytes);
  412. ret = -EINVAL;
  413. }
  414. btrfs_free_extent_map(em);
  415. out:
  416. ret2 = free_extent_map_tree(inode);
  417. if (ret == 0)
  418. ret = ret2;
  419. return ret;
  420. }
  421. /*
  422. * Test scenario:
  423. *
  424. * Suppose that no extent map has been loaded into memory yet.
  425. * There is a file extent [0, 32K), two jobs are running concurrently
  426. * against it, t1 is doing dio write to [8K, 32K) and t2 is doing dio
  427. * read from [0, 4K) or [4K, 8K).
  428. *
  429. * t1 goes ahead of t2 and splits em [0, 32K) to em [0K, 8K) and [8K 32K).
  430. *
  431. * t1 t2
  432. * btrfs_get_blocks_direct() btrfs_get_blocks_direct()
  433. * -> btrfs_get_extent() -> btrfs_get_extent()
  434. * -> lookup_extent_mapping()
  435. * -> add_extent_mapping() -> lookup_extent_mapping()
  436. * # load [0, 32K)
  437. * -> btrfs_new_extent_direct()
  438. * -> btrfs_drop_extent_cache()
  439. * # split [0, 32K)
  440. * -> add_extent_mapping()
  441. * # add [8K, 32K)
  442. * -> add_extent_mapping()
  443. * # handle -EEXIST when adding
  444. * # [0, 32K)
  445. */
  446. static int test_case_4(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
  447. {
  448. int ret;
  449. ret = __test_case_4(fs_info, inode, 0);
  450. if (ret)
  451. return ret;
  452. ret = __test_case_4(fs_info, inode, SZ_4K);
  453. return ret;
  454. }
  455. static int add_compressed_extent(struct btrfs_inode *inode,
  456. u64 start, u64 len, u64 block_start)
  457. {
  458. struct extent_map_tree *em_tree = &inode->extent_tree;
  459. struct extent_map *em;
  460. int ret;
  461. em = btrfs_alloc_extent_map();
  462. if (!em) {
  463. test_std_err(TEST_ALLOC_EXTENT_MAP);
  464. return -ENOMEM;
  465. }
  466. em->start = start;
  467. em->len = len;
  468. em->disk_bytenr = block_start;
  469. em->disk_num_bytes = SZ_4K;
  470. em->ram_bytes = len;
  471. em->flags |= EXTENT_FLAG_COMPRESS_ZLIB;
  472. write_lock(&em_tree->lock);
  473. ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
  474. write_unlock(&em_tree->lock);
  475. btrfs_free_extent_map(em);
  476. if (ret < 0) {
  477. test_err("cannot add extent map [%llu, %llu)", start, start + len);
  478. return ret;
  479. }
  480. return 0;
  481. }
  482. struct extent_range {
  483. u64 start;
  484. u64 len;
  485. };
  486. /* The valid states of the tree after every drop, as described below. */
  487. struct extent_range valid_ranges[][7] = {
  488. {
  489. { .start = 0, .len = SZ_8K }, /* [0, 8K) */
  490. { .start = SZ_4K * 3, .len = SZ_4K * 3}, /* [12k, 24k) */
  491. { .start = SZ_4K * 6, .len = SZ_4K * 3}, /* [24k, 36k) */
  492. { .start = SZ_32K + SZ_4K, .len = SZ_4K}, /* [36k, 40k) */
  493. { .start = SZ_4K * 10, .len = SZ_4K * 6}, /* [40k, 64k) */
  494. },
  495. {
  496. { .start = 0, .len = SZ_8K }, /* [0, 8K) */
  497. { .start = SZ_4K * 5, .len = SZ_4K}, /* [20k, 24k) */
  498. { .start = SZ_4K * 6, .len = SZ_4K * 3}, /* [24k, 36k) */
  499. { .start = SZ_32K + SZ_4K, .len = SZ_4K}, /* [36k, 40k) */
  500. { .start = SZ_4K * 10, .len = SZ_4K * 6}, /* [40k, 64k) */
  501. },
  502. {
  503. { .start = 0, .len = SZ_8K }, /* [0, 8K) */
  504. { .start = SZ_4K * 5, .len = SZ_4K}, /* [20k, 24k) */
  505. { .start = SZ_4K * 6, .len = SZ_4K}, /* [24k, 28k) */
  506. { .start = SZ_32K, .len = SZ_4K}, /* [32k, 36k) */
  507. { .start = SZ_32K + SZ_4K, .len = SZ_4K}, /* [36k, 40k) */
  508. { .start = SZ_4K * 10, .len = SZ_4K * 6}, /* [40k, 64k) */
  509. },
  510. {
  511. { .start = 0, .len = SZ_8K}, /* [0, 8K) */
  512. { .start = SZ_4K * 5, .len = SZ_4K}, /* [20k, 24k) */
  513. { .start = SZ_4K * 6, .len = SZ_4K}, /* [24k, 28k) */
  514. }
  515. };
  516. static int validate_range(struct extent_map_tree *em_tree, int index)
  517. {
  518. struct rb_node *n;
  519. int i;
  520. for (i = 0, n = rb_first(&em_tree->root);
  521. valid_ranges[index][i].len && n;
  522. i++, n = rb_next(n)) {
  523. struct extent_map *entry = rb_entry(n, struct extent_map, rb_node);
  524. if (entry->start != valid_ranges[index][i].start) {
  525. test_err("mapping has start %llu expected %llu",
  526. entry->start, valid_ranges[index][i].start);
  527. return -EINVAL;
  528. }
  529. if (entry->len != valid_ranges[index][i].len) {
  530. test_err("mapping has len %llu expected %llu",
  531. entry->len, valid_ranges[index][i].len);
  532. return -EINVAL;
  533. }
  534. }
  535. /*
  536. * We exited because we don't have any more entries in the extent_map
  537. * but we still expect more valid entries.
  538. */
  539. if (valid_ranges[index][i].len) {
  540. test_err("missing an entry");
  541. return -EINVAL;
  542. }
  543. /* We exited the loop but still have entries in the extent map. */
  544. if (n) {
  545. test_err("we have a left over entry in the extent map we didn't expect");
  546. return -EINVAL;
  547. }
  548. return 0;
  549. }
  550. /*
  551. * Test scenario:
  552. *
  553. * Test the various edge cases of btrfs_drop_extent_map_range, create the
  554. * following ranges
  555. *
  556. * [0, 12k)[12k, 24k)[24k, 36k)[36k, 40k)[40k,64k)
  557. *
  558. * And then we'll drop:
  559. *
  560. * [8k, 12k) - test the single front split
  561. * [12k, 20k) - test the single back split
  562. * [28k, 32k) - test the double split
  563. * [32k, 64k) - test whole em dropping
  564. *
  565. * They'll have the EXTENT_FLAG_COMPRESSED flag set to keep the em tree from
  566. * merging the em's.
  567. */
  568. static int test_case_5(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
  569. {
  570. u64 start, end;
  571. int ret;
  572. int ret2;
  573. test_msg("Running btrfs_drop_extent_map_range tests");
  574. /* [0, 12k) */
  575. ret = add_compressed_extent(inode, 0, SZ_4K * 3, 0);
  576. if (ret) {
  577. test_err("cannot add extent range [0, 12K)");
  578. goto out;
  579. }
  580. /* [12k, 24k) */
  581. ret = add_compressed_extent(inode, SZ_4K * 3, SZ_4K * 3, SZ_4K);
  582. if (ret) {
  583. test_err("cannot add extent range [12k, 24k)");
  584. goto out;
  585. }
  586. /* [24k, 36k) */
  587. ret = add_compressed_extent(inode, SZ_4K * 6, SZ_4K * 3, SZ_8K);
  588. if (ret) {
  589. test_err("cannot add extent range [12k, 24k)");
  590. goto out;
  591. }
  592. /* [36k, 40k) */
  593. ret = add_compressed_extent(inode, SZ_32K + SZ_4K, SZ_4K, SZ_4K * 3);
  594. if (ret) {
  595. test_err("cannot add extent range [12k, 24k)");
  596. goto out;
  597. }
  598. /* [40k, 64k) */
  599. ret = add_compressed_extent(inode, SZ_4K * 10, SZ_4K * 6, SZ_16K);
  600. if (ret) {
  601. test_err("cannot add extent range [12k, 24k)");
  602. goto out;
  603. }
  604. /* Drop [8k, 12k) */
  605. start = SZ_8K;
  606. end = (3 * SZ_4K) - 1;
  607. btrfs_drop_extent_map_range(inode, start, end, false);
  608. ret = validate_range(&inode->extent_tree, 0);
  609. if (ret)
  610. goto out;
  611. /* Drop [12k, 20k) */
  612. start = SZ_4K * 3;
  613. end = SZ_16K + SZ_4K - 1;
  614. btrfs_drop_extent_map_range(inode, start, end, false);
  615. ret = validate_range(&inode->extent_tree, 1);
  616. if (ret)
  617. goto out;
  618. /* Drop [28k, 32k) */
  619. start = SZ_32K - SZ_4K;
  620. end = SZ_32K - 1;
  621. btrfs_drop_extent_map_range(inode, start, end, false);
  622. ret = validate_range(&inode->extent_tree, 2);
  623. if (ret)
  624. goto out;
  625. /* Drop [32k, 64k) */
  626. start = SZ_32K;
  627. end = SZ_64K - 1;
  628. btrfs_drop_extent_map_range(inode, start, end, false);
  629. ret = validate_range(&inode->extent_tree, 3);
  630. if (ret)
  631. goto out;
  632. out:
  633. ret2 = free_extent_map_tree(inode);
  634. if (ret == 0)
  635. ret = ret2;
  636. return ret;
  637. }
  638. /*
  639. * Test the btrfs_add_extent_mapping helper which will attempt to create an em
  640. * for areas between two existing ems. Validate it doesn't do this when there
  641. * are two unmerged em's side by side.
  642. */
  643. static int test_case_6(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
  644. {
  645. struct extent_map_tree *em_tree = &inode->extent_tree;
  646. struct extent_map *em = NULL;
  647. int ret;
  648. int ret2;
  649. ret = add_compressed_extent(inode, 0, SZ_4K, 0);
  650. if (ret)
  651. goto out;
  652. ret = add_compressed_extent(inode, SZ_4K, SZ_4K, 0);
  653. if (ret)
  654. goto out;
  655. em = btrfs_alloc_extent_map();
  656. if (!em) {
  657. test_std_err(TEST_ALLOC_EXTENT_MAP);
  658. ret = -ENOMEM;
  659. goto out;
  660. }
  661. em->start = SZ_4K;
  662. em->len = SZ_4K;
  663. em->disk_bytenr = SZ_16K;
  664. em->disk_num_bytes = SZ_16K;
  665. em->ram_bytes = SZ_16K;
  666. write_lock(&em_tree->lock);
  667. ret = btrfs_add_extent_mapping(inode, &em, 0, SZ_8K);
  668. write_unlock(&em_tree->lock);
  669. if (ret != 0) {
  670. test_err("got an error when adding our em: %d", ret);
  671. goto out;
  672. }
  673. ret = -EINVAL;
  674. if (em->start != 0) {
  675. test_err("unexpected em->start at %llu, wanted 0", em->start);
  676. goto out;
  677. }
  678. if (em->len != SZ_4K) {
  679. test_err("unexpected em->len %llu, expected 4K", em->len);
  680. goto out;
  681. }
  682. ret = 0;
  683. out:
  684. btrfs_free_extent_map(em);
  685. ret2 = free_extent_map_tree(inode);
  686. if (ret == 0)
  687. ret = ret2;
  688. return ret;
  689. }
  690. /*
  691. * Regression test for btrfs_drop_extent_map_range. Calling with skip_pinned ==
  692. * true would mess up the start/end calculations and subsequent splits would be
  693. * incorrect.
  694. */
  695. static int test_case_7(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
  696. {
  697. struct extent_map_tree *em_tree = &inode->extent_tree;
  698. struct extent_map *em;
  699. int ret;
  700. int ret2;
  701. test_msg("Running btrfs_drop_extent_cache with pinned");
  702. em = btrfs_alloc_extent_map();
  703. if (!em) {
  704. test_std_err(TEST_ALLOC_EXTENT_MAP);
  705. return -ENOMEM;
  706. }
  707. /* [0, 16K), pinned */
  708. em->start = 0;
  709. em->len = SZ_16K;
  710. em->disk_bytenr = 0;
  711. em->disk_num_bytes = SZ_4K;
  712. em->ram_bytes = SZ_16K;
  713. em->flags |= (EXTENT_FLAG_PINNED | EXTENT_FLAG_COMPRESS_ZLIB);
  714. write_lock(&em_tree->lock);
  715. ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
  716. write_unlock(&em_tree->lock);
  717. if (ret < 0) {
  718. test_err("couldn't add extent map");
  719. goto out;
  720. }
  721. btrfs_free_extent_map(em);
  722. em = btrfs_alloc_extent_map();
  723. if (!em) {
  724. test_std_err(TEST_ALLOC_EXTENT_MAP);
  725. ret = -ENOMEM;
  726. goto out;
  727. }
  728. /* [32K, 48K), not pinned */
  729. em->start = SZ_32K;
  730. em->len = SZ_16K;
  731. em->disk_bytenr = SZ_32K;
  732. em->disk_num_bytes = SZ_16K;
  733. em->ram_bytes = SZ_16K;
  734. write_lock(&em_tree->lock);
  735. ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
  736. write_unlock(&em_tree->lock);
  737. if (ret < 0) {
  738. test_err("couldn't add extent map");
  739. goto out;
  740. }
  741. btrfs_free_extent_map(em);
  742. /*
  743. * Drop [0, 36K) This should skip the [0, 4K) extent and then split the
  744. * [32K, 48K) extent.
  745. */
  746. btrfs_drop_extent_map_range(inode, 0, (36 * SZ_1K) - 1, true);
  747. /* Make sure our extent maps look sane. */
  748. ret = -EINVAL;
  749. em = btrfs_lookup_extent_mapping(em_tree, 0, SZ_16K);
  750. if (!em) {
  751. test_err("didn't find an em at 0 as expected");
  752. goto out;
  753. }
  754. if (em->start != 0) {
  755. test_err("em->start is %llu, expected 0", em->start);
  756. goto out;
  757. }
  758. if (em->len != SZ_16K) {
  759. test_err("em->len is %llu, expected 16K", em->len);
  760. goto out;
  761. }
  762. btrfs_free_extent_map(em);
  763. read_lock(&em_tree->lock);
  764. em = btrfs_lookup_extent_mapping(em_tree, SZ_16K, SZ_16K);
  765. read_unlock(&em_tree->lock);
  766. if (em) {
  767. test_err("found an em when we weren't expecting one");
  768. goto out;
  769. }
  770. read_lock(&em_tree->lock);
  771. em = btrfs_lookup_extent_mapping(em_tree, SZ_32K, SZ_16K);
  772. read_unlock(&em_tree->lock);
  773. if (!em) {
  774. test_err("didn't find an em at 32K as expected");
  775. goto out;
  776. }
  777. if (em->start != (36 * SZ_1K)) {
  778. test_err("em->start is %llu, expected 36K", em->start);
  779. goto out;
  780. }
  781. if (em->len != (12 * SZ_1K)) {
  782. test_err("em->len is %llu, expected 12K", em->len);
  783. goto out;
  784. }
  785. if (btrfs_extent_map_block_start(em) != SZ_32K + SZ_4K) {
  786. test_err("em->block_start is %llu, expected 36K",
  787. btrfs_extent_map_block_start(em));
  788. goto out;
  789. }
  790. btrfs_free_extent_map(em);
  791. read_lock(&em_tree->lock);
  792. em = btrfs_lookup_extent_mapping(em_tree, 48 * SZ_1K, (u64)-1);
  793. read_unlock(&em_tree->lock);
  794. if (em) {
  795. test_err("found an unexpected em above 48K");
  796. goto out;
  797. }
  798. ret = 0;
  799. out:
  800. btrfs_free_extent_map(em);
  801. /* Unpin our extent to prevent warning when removing it below. */
  802. ret2 = btrfs_unpin_extent_cache(inode, 0, SZ_16K, 0);
  803. if (ret == 0)
  804. ret = ret2;
  805. ret2 = free_extent_map_tree(inode);
  806. if (ret == 0)
  807. ret = ret2;
  808. return ret;
  809. }
  810. /*
  811. * Test a regression for compressed extent map adjustment when we attempt to
  812. * add an extent map that is partially overlapped by another existing extent
  813. * map. The resulting extent map offset was left unchanged despite having
  814. * incremented its start offset.
  815. */
  816. static int test_case_8(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
  817. {
  818. struct extent_map_tree *em_tree = &inode->extent_tree;
  819. struct extent_map *em;
  820. int ret;
  821. int ret2;
  822. em = btrfs_alloc_extent_map();
  823. if (!em) {
  824. test_std_err(TEST_ALLOC_EXTENT_MAP);
  825. return -ENOMEM;
  826. }
  827. /* Compressed extent for the file range [120K, 128K). */
  828. em->start = SZ_1K * 120;
  829. em->len = SZ_8K;
  830. em->disk_num_bytes = SZ_4K;
  831. em->ram_bytes = SZ_8K;
  832. em->flags |= EXTENT_FLAG_COMPRESS_ZLIB;
  833. write_lock(&em_tree->lock);
  834. ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
  835. write_unlock(&em_tree->lock);
  836. btrfs_free_extent_map(em);
  837. if (ret < 0) {
  838. test_err("couldn't add extent map for range [120K, 128K)");
  839. goto out;
  840. }
  841. em = btrfs_alloc_extent_map();
  842. if (!em) {
  843. test_std_err(TEST_ALLOC_EXTENT_MAP);
  844. ret = -ENOMEM;
  845. goto out;
  846. }
  847. /*
  848. * Compressed extent for the file range [108K, 144K), which overlaps
  849. * with the [120K, 128K) we previously inserted.
  850. */
  851. em->start = SZ_1K * 108;
  852. em->len = SZ_1K * 36;
  853. em->disk_num_bytes = SZ_4K;
  854. em->ram_bytes = SZ_1K * 36;
  855. em->flags |= EXTENT_FLAG_COMPRESS_ZLIB;
  856. /*
  857. * Try to add the extent map but with a search range of [140K, 144K),
  858. * this should succeed and adjust the extent map to the range
  859. * [128K, 144K), with a length of 16K and an offset of 20K.
  860. *
  861. * This simulates a scenario where in the subvolume tree of an inode we
  862. * have a compressed file extent item for the range [108K, 144K) and we
  863. * have an overlapping compressed extent map for the range [120K, 128K),
  864. * which was created by an encoded write, but its ordered extent was not
  865. * yet completed, so the subvolume tree doesn't have yet the file extent
  866. * item for that range - we only have the extent map in the inode's
  867. * extent map tree.
  868. */
  869. write_lock(&em_tree->lock);
  870. ret = btrfs_add_extent_mapping(inode, &em, SZ_1K * 140, SZ_4K);
  871. write_unlock(&em_tree->lock);
  872. btrfs_free_extent_map(em);
  873. if (ret < 0) {
  874. test_err("couldn't add extent map for range [108K, 144K)");
  875. goto out;
  876. }
  877. if (em->start != SZ_128K) {
  878. test_err("unexpected extent map start %llu (should be 128K)", em->start);
  879. ret = -EINVAL;
  880. goto out;
  881. }
  882. if (em->len != SZ_16K) {
  883. test_err("unexpected extent map length %llu (should be 16K)", em->len);
  884. ret = -EINVAL;
  885. goto out;
  886. }
  887. if (em->offset != SZ_1K * 20) {
  888. test_err("unexpected extent map offset %llu (should be 20K)", em->offset);
  889. ret = -EINVAL;
  890. goto out;
  891. }
  892. out:
  893. ret2 = free_extent_map_tree(inode);
  894. if (ret == 0)
  895. ret = ret2;
  896. return ret;
  897. }
  898. struct rmap_test_vector {
  899. u64 raid_type;
  900. u64 physical_start;
  901. u64 data_stripe_size;
  902. u64 num_data_stripes;
  903. u64 num_stripes;
  904. /* Assume we won't have more than 5 physical stripes */
  905. u64 data_stripe_phys_start[5];
  906. bool expected_mapped_addr;
  907. /* Physical to logical addresses */
  908. u64 mapped_logical[5];
  909. };
  910. static int test_rmap_block(struct btrfs_fs_info *fs_info,
  911. struct rmap_test_vector *test)
  912. {
  913. struct btrfs_chunk_map *map;
  914. u64 AUTO_KFREE(logical);
  915. int i, out_ndaddrs, out_stripe_len;
  916. int ret;
  917. map = btrfs_alloc_chunk_map(test->num_stripes, GFP_KERNEL);
  918. if (!map) {
  919. test_std_err(TEST_ALLOC_CHUNK_MAP);
  920. return -ENOMEM;
  921. }
  922. /* Start at 4GiB logical address */
  923. map->start = SZ_4G;
  924. map->chunk_len = test->data_stripe_size * test->num_data_stripes;
  925. map->stripe_size = test->data_stripe_size;
  926. map->num_stripes = test->num_stripes;
  927. map->type = test->raid_type;
  928. for (i = 0; i < map->num_stripes; i++) {
  929. struct btrfs_device *dev = btrfs_alloc_dummy_device(fs_info);
  930. if (IS_ERR(dev)) {
  931. test_err("cannot allocate device");
  932. ret = PTR_ERR(dev);
  933. goto out;
  934. }
  935. map->stripes[i].dev = dev;
  936. map->stripes[i].physical = test->data_stripe_phys_start[i];
  937. }
  938. ret = btrfs_add_chunk_map(fs_info, map);
  939. if (ret) {
  940. test_err("error adding chunk map to mapping tree");
  941. btrfs_free_chunk_map(map);
  942. return ret;
  943. }
  944. ret = btrfs_rmap_block(fs_info, map->start, btrfs_sb_offset(1),
  945. &logical, &out_ndaddrs, &out_stripe_len);
  946. if (ret || (out_ndaddrs == 0 && test->expected_mapped_addr)) {
  947. test_err("didn't rmap anything but expected %d",
  948. test->expected_mapped_addr);
  949. goto out;
  950. }
  951. if (out_stripe_len != BTRFS_STRIPE_LEN) {
  952. test_err("calculated stripe length doesn't match");
  953. ret = -EINVAL;
  954. goto out;
  955. }
  956. if (out_ndaddrs != test->expected_mapped_addr) {
  957. for (i = 0; i < out_ndaddrs; i++)
  958. test_msg("mapped %llu", logical[i]);
  959. test_err("unexpected number of mapped addresses: %d", out_ndaddrs);
  960. ret = -EINVAL;
  961. goto out;
  962. }
  963. for (i = 0; i < out_ndaddrs; i++) {
  964. if (logical[i] != test->mapped_logical[i]) {
  965. test_err("unexpected logical address mapped");
  966. ret = -EINVAL;
  967. goto out;
  968. }
  969. }
  970. ret = 0;
  971. out:
  972. btrfs_remove_chunk_map(fs_info, map);
  973. return ret;
  974. }
  975. int btrfs_test_extent_map(void)
  976. {
  977. struct btrfs_fs_info *fs_info = NULL;
  978. struct inode *inode;
  979. struct btrfs_root *root = NULL;
  980. int ret = 0, i;
  981. struct rmap_test_vector rmap_tests[] = {
  982. {
  983. /*
  984. * Test a chunk with 2 data stripes one of which
  985. * intersects the physical address of the super block
  986. * is correctly recognized.
  987. */
  988. .raid_type = BTRFS_BLOCK_GROUP_RAID1,
  989. .physical_start = SZ_64M - SZ_4M,
  990. .data_stripe_size = SZ_256M,
  991. .num_data_stripes = 2,
  992. .num_stripes = 2,
  993. .data_stripe_phys_start =
  994. {SZ_64M - SZ_4M, SZ_64M - SZ_4M + SZ_256M},
  995. .expected_mapped_addr = true,
  996. .mapped_logical= {SZ_4G + SZ_4M}
  997. },
  998. {
  999. /*
  1000. * Test that out-of-range physical addresses are
  1001. * ignored
  1002. */
  1003. /* SINGLE chunk type */
  1004. .raid_type = 0,
  1005. .physical_start = SZ_4G,
  1006. .data_stripe_size = SZ_256M,
  1007. .num_data_stripes = 1,
  1008. .num_stripes = 1,
  1009. .data_stripe_phys_start = {SZ_256M},
  1010. .expected_mapped_addr = false,
  1011. .mapped_logical = {0}
  1012. }
  1013. };
  1014. test_msg("running extent_map tests");
  1015. /*
  1016. * Note: the fs_info is not set up completely, we only need
  1017. * fs_info::fsid for the tracepoint.
  1018. *
  1019. * And all the immediate numbers are based on 4K blocksize,
  1020. * thus we have to use 4K as sectorsize no matter the page size.
  1021. */
  1022. fs_info = btrfs_alloc_dummy_fs_info(SZ_4K, SZ_4K);
  1023. if (!fs_info) {
  1024. test_std_err(TEST_ALLOC_FS_INFO);
  1025. return -ENOMEM;
  1026. }
  1027. inode = btrfs_new_test_inode();
  1028. if (!inode) {
  1029. test_std_err(TEST_ALLOC_INODE);
  1030. ret = -ENOMEM;
  1031. goto out;
  1032. }
  1033. root = btrfs_alloc_dummy_root(fs_info);
  1034. if (IS_ERR(root)) {
  1035. test_std_err(TEST_ALLOC_ROOT);
  1036. ret = PTR_ERR(root);
  1037. root = NULL;
  1038. goto out;
  1039. }
  1040. BTRFS_I(inode)->root = root;
  1041. ret = test_case_1(fs_info, BTRFS_I(inode));
  1042. if (ret)
  1043. goto out;
  1044. ret = test_case_2(fs_info, BTRFS_I(inode));
  1045. if (ret)
  1046. goto out;
  1047. ret = test_case_3(fs_info, BTRFS_I(inode));
  1048. if (ret)
  1049. goto out;
  1050. ret = test_case_4(fs_info, BTRFS_I(inode));
  1051. if (ret)
  1052. goto out;
  1053. ret = test_case_5(fs_info, BTRFS_I(inode));
  1054. if (ret)
  1055. goto out;
  1056. ret = test_case_6(fs_info, BTRFS_I(inode));
  1057. if (ret)
  1058. goto out;
  1059. ret = test_case_7(fs_info, BTRFS_I(inode));
  1060. if (ret)
  1061. goto out;
  1062. ret = test_case_8(fs_info, BTRFS_I(inode));
  1063. if (ret)
  1064. goto out;
  1065. test_msg("running rmap tests");
  1066. for (i = 0; i < ARRAY_SIZE(rmap_tests); i++) {
  1067. ret = test_rmap_block(fs_info, &rmap_tests[i]);
  1068. if (ret)
  1069. goto out;
  1070. }
  1071. out:
  1072. iput(inode);
  1073. btrfs_free_dummy_root(root);
  1074. btrfs_free_dummy_fs_info(fs_info);
  1075. return ret;
  1076. }