inode-tests.c 32 KB

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