inode-tests.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955
  1. /*
  2. * Copyright (C) 2013 Fusion IO. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public
  6. * License v2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public
  14. * License along with this program; if not, write to the
  15. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  16. * Boston, MA 021110-1307, USA.
  17. */
  18. #include "btrfs-tests.h"
  19. #include "../ctree.h"
  20. #include "../btrfs_inode.h"
  21. #include "../disk-io.h"
  22. #include "../extent_io.h"
  23. #include "../volumes.h"
  24. static struct btrfs_fs_info *alloc_dummy_fs_info(void)
  25. {
  26. struct btrfs_fs_info *fs_info = kzalloc(sizeof(struct btrfs_fs_info),
  27. GFP_NOFS);
  28. if (!fs_info)
  29. return fs_info;
  30. fs_info->fs_devices = kzalloc(sizeof(struct btrfs_fs_devices),
  31. GFP_NOFS);
  32. if (!fs_info->fs_devices) {
  33. kfree(fs_info);
  34. return NULL;
  35. }
  36. return fs_info;
  37. }
  38. static void free_dummy_root(struct btrfs_root *root)
  39. {
  40. if (!root)
  41. return;
  42. if (root->fs_info) {
  43. kfree(root->fs_info->fs_devices);
  44. kfree(root->fs_info);
  45. }
  46. if (root->node)
  47. free_extent_buffer(root->node);
  48. kfree(root);
  49. }
  50. static void insert_extent(struct btrfs_root *root, u64 start, u64 len,
  51. u64 ram_bytes, u64 offset, u64 disk_bytenr,
  52. u64 disk_len, u32 type, u8 compression, int slot)
  53. {
  54. struct btrfs_path path;
  55. struct btrfs_file_extent_item *fi;
  56. struct extent_buffer *leaf = root->node;
  57. struct btrfs_key key;
  58. u32 value_len = sizeof(struct btrfs_file_extent_item);
  59. if (type == BTRFS_FILE_EXTENT_INLINE)
  60. value_len += len;
  61. memset(&path, 0, sizeof(path));
  62. path.nodes[0] = leaf;
  63. path.slots[0] = slot;
  64. key.objectid = BTRFS_FIRST_FREE_OBJECTID;
  65. key.type = BTRFS_EXTENT_DATA_KEY;
  66. key.offset = start;
  67. setup_items_for_insert(root, &path, &key, &value_len, value_len,
  68. value_len + sizeof(struct btrfs_item), 1);
  69. fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
  70. btrfs_set_file_extent_generation(leaf, fi, 1);
  71. btrfs_set_file_extent_type(leaf, fi, type);
  72. btrfs_set_file_extent_disk_bytenr(leaf, fi, disk_bytenr);
  73. btrfs_set_file_extent_disk_num_bytes(leaf, fi, disk_len);
  74. btrfs_set_file_extent_offset(leaf, fi, offset);
  75. btrfs_set_file_extent_num_bytes(leaf, fi, len);
  76. btrfs_set_file_extent_ram_bytes(leaf, fi, ram_bytes);
  77. btrfs_set_file_extent_compression(leaf, fi, compression);
  78. btrfs_set_file_extent_encryption(leaf, fi, 0);
  79. btrfs_set_file_extent_other_encoding(leaf, fi, 0);
  80. }
  81. static void insert_inode_item_key(struct btrfs_root *root)
  82. {
  83. struct btrfs_path path;
  84. struct extent_buffer *leaf = root->node;
  85. struct btrfs_key key;
  86. u32 value_len = 0;
  87. memset(&path, 0, sizeof(path));
  88. path.nodes[0] = leaf;
  89. path.slots[0] = 0;
  90. key.objectid = BTRFS_INODE_ITEM_KEY;
  91. key.type = BTRFS_INODE_ITEM_KEY;
  92. key.offset = 0;
  93. setup_items_for_insert(root, &path, &key, &value_len, value_len,
  94. value_len + sizeof(struct btrfs_item), 1);
  95. }
  96. /*
  97. * Build the most complicated map of extents the earth has ever seen. We want
  98. * this so we can test all of the corner cases of btrfs_get_extent. Here is a
  99. * diagram of how the extents will look though this may not be possible we still
  100. * want to make sure everything acts normally (the last number is not inclusive)
  101. *
  102. * [0 - 5][5 - 6][6 - 10][10 - 4096][ 4096 - 8192 ][8192 - 12288]
  103. * [hole ][inline][ hole ][ regular ][regular1 split][ hole ]
  104. *
  105. * [ 12288 - 20480][20480 - 24576][ 24576 - 28672 ][28672 - 36864][36864 - 45056]
  106. * [regular1 split][ prealloc1 ][prealloc1 written][ prealloc1 ][ compressed ]
  107. *
  108. * [45056 - 49152][49152-53248][53248-61440][61440-65536][ 65536+81920 ]
  109. * [ compressed1 ][ regular ][compressed1][ regular ][ hole but no extent]
  110. *
  111. * [81920-86016]
  112. * [ regular ]
  113. */
  114. static void setup_file_extents(struct btrfs_root *root)
  115. {
  116. int slot = 0;
  117. u64 disk_bytenr = 1 * 1024 * 1024;
  118. u64 offset = 0;
  119. /* First we want a hole */
  120. insert_extent(root, offset, 5, 5, 0, 0, 0, BTRFS_FILE_EXTENT_REG, 0,
  121. slot);
  122. slot++;
  123. offset += 5;
  124. /*
  125. * Now we want an inline extent, I don't think this is possible but hey
  126. * why not? Also keep in mind if we have an inline extent it counts as
  127. * the whole first page. If we were to expand it we would have to cow
  128. * and we wouldn't have an inline extent anymore.
  129. */
  130. insert_extent(root, offset, 1, 1, 0, 0, 0, BTRFS_FILE_EXTENT_INLINE, 0,
  131. slot);
  132. slot++;
  133. offset = 4096;
  134. /* Now another hole */
  135. insert_extent(root, offset, 4, 4, 0, 0, 0, BTRFS_FILE_EXTENT_REG, 0,
  136. slot);
  137. slot++;
  138. offset += 4;
  139. /* Now for a regular extent */
  140. insert_extent(root, offset, 4095, 4095, 0, disk_bytenr, 4096,
  141. BTRFS_FILE_EXTENT_REG, 0, slot);
  142. slot++;
  143. disk_bytenr += 4096;
  144. offset += 4095;
  145. /*
  146. * Now for 3 extents that were split from a hole punch so we test
  147. * offsets properly.
  148. */
  149. insert_extent(root, offset, 4096, 16384, 0, disk_bytenr, 16384,
  150. BTRFS_FILE_EXTENT_REG, 0, slot);
  151. slot++;
  152. offset += 4096;
  153. insert_extent(root, offset, 4096, 4096, 0, 0, 0, BTRFS_FILE_EXTENT_REG,
  154. 0, slot);
  155. slot++;
  156. offset += 4096;
  157. insert_extent(root, offset, 8192, 16384, 8192, disk_bytenr, 16384,
  158. BTRFS_FILE_EXTENT_REG, 0, slot);
  159. slot++;
  160. offset += 8192;
  161. disk_bytenr += 16384;
  162. /* Now for a unwritten prealloc extent */
  163. insert_extent(root, offset, 4096, 4096, 0, disk_bytenr, 4096,
  164. BTRFS_FILE_EXTENT_PREALLOC, 0, slot);
  165. slot++;
  166. offset += 4096;
  167. /*
  168. * We want to jack up disk_bytenr a little more so the em stuff doesn't
  169. * merge our records.
  170. */
  171. disk_bytenr += 8192;
  172. /*
  173. * Now for a partially written prealloc extent, basically the same as
  174. * the hole punch example above. Ram_bytes never changes when you mark
  175. * extents written btw.
  176. */
  177. insert_extent(root, offset, 4096, 16384, 0, disk_bytenr, 16384,
  178. BTRFS_FILE_EXTENT_PREALLOC, 0, slot);
  179. slot++;
  180. offset += 4096;
  181. insert_extent(root, offset, 4096, 16384, 4096, disk_bytenr, 16384,
  182. BTRFS_FILE_EXTENT_REG, 0, slot);
  183. slot++;
  184. offset += 4096;
  185. insert_extent(root, offset, 8192, 16384, 8192, disk_bytenr, 16384,
  186. BTRFS_FILE_EXTENT_PREALLOC, 0, slot);
  187. slot++;
  188. offset += 8192;
  189. disk_bytenr += 16384;
  190. /* Now a normal compressed extent */
  191. insert_extent(root, offset, 8192, 8192, 0, disk_bytenr, 4096,
  192. BTRFS_FILE_EXTENT_REG, BTRFS_COMPRESS_ZLIB, slot);
  193. slot++;
  194. offset += 8192;
  195. /* No merges */
  196. disk_bytenr += 8192;
  197. /* Now a split compressed extent */
  198. insert_extent(root, offset, 4096, 16384, 0, disk_bytenr, 4096,
  199. BTRFS_FILE_EXTENT_REG, BTRFS_COMPRESS_ZLIB, slot);
  200. slot++;
  201. offset += 4096;
  202. insert_extent(root, offset, 4096, 4096, 0, disk_bytenr + 4096, 4096,
  203. BTRFS_FILE_EXTENT_REG, 0, slot);
  204. slot++;
  205. offset += 4096;
  206. insert_extent(root, offset, 8192, 16384, 8192, disk_bytenr, 4096,
  207. BTRFS_FILE_EXTENT_REG, BTRFS_COMPRESS_ZLIB, slot);
  208. slot++;
  209. offset += 8192;
  210. disk_bytenr += 8192;
  211. /* Now extents that have a hole but no hole extent */
  212. insert_extent(root, offset, 4096, 4096, 0, disk_bytenr, 4096,
  213. BTRFS_FILE_EXTENT_REG, 0, slot);
  214. slot++;
  215. offset += 16384;
  216. disk_bytenr += 4096;
  217. insert_extent(root, offset, 4096, 4096, 0, disk_bytenr, 4096,
  218. BTRFS_FILE_EXTENT_REG, 0, slot);
  219. }
  220. static unsigned long prealloc_only = 0;
  221. static unsigned long compressed_only = 0;
  222. static unsigned long vacancy_only = 0;
  223. static noinline int test_btrfs_get_extent(void)
  224. {
  225. struct inode *inode = NULL;
  226. struct btrfs_root *root = NULL;
  227. struct extent_map *em = NULL;
  228. u64 orig_start;
  229. u64 disk_bytenr;
  230. u64 offset;
  231. int ret = -ENOMEM;
  232. inode = btrfs_new_test_inode();
  233. if (!inode) {
  234. test_msg("Couldn't allocate inode\n");
  235. return ret;
  236. }
  237. BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY;
  238. BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID;
  239. BTRFS_I(inode)->location.offset = 0;
  240. root = btrfs_alloc_dummy_root();
  241. if (IS_ERR(root)) {
  242. test_msg("Couldn't allocate root\n");
  243. goto out;
  244. }
  245. /*
  246. * We do this since btrfs_get_extent wants to assign em->bdev to
  247. * root->fs_info->fs_devices->latest_bdev.
  248. */
  249. root->fs_info = alloc_dummy_fs_info();
  250. if (!root->fs_info) {
  251. test_msg("Couldn't allocate dummy fs info\n");
  252. goto out;
  253. }
  254. root->node = alloc_dummy_extent_buffer(0, 4096);
  255. if (!root->node) {
  256. test_msg("Couldn't allocate dummy buffer\n");
  257. goto out;
  258. }
  259. /*
  260. * We will just free a dummy node if it's ref count is 2 so we need an
  261. * extra ref so our searches don't accidently release our page.
  262. */
  263. extent_buffer_get(root->node);
  264. btrfs_set_header_nritems(root->node, 0);
  265. btrfs_set_header_level(root->node, 0);
  266. ret = -EINVAL;
  267. /* First with no extents */
  268. BTRFS_I(inode)->root = root;
  269. em = btrfs_get_extent(inode, NULL, 0, 0, 4096, 0);
  270. if (IS_ERR(em)) {
  271. em = NULL;
  272. test_msg("Got an error when we shouldn't have\n");
  273. goto out;
  274. }
  275. if (em->block_start != EXTENT_MAP_HOLE) {
  276. test_msg("Expected a hole, got %llu\n", em->block_start);
  277. goto out;
  278. }
  279. if (!test_bit(EXTENT_FLAG_VACANCY, &em->flags)) {
  280. test_msg("Vacancy flag wasn't set properly\n");
  281. goto out;
  282. }
  283. free_extent_map(em);
  284. btrfs_drop_extent_cache(inode, 0, (u64)-1, 0);
  285. /*
  286. * All of the magic numbers are based on the mapping setup in
  287. * setup_file_extents, so if you change anything there you need to
  288. * update the comment and update the expected values below.
  289. */
  290. setup_file_extents(root);
  291. em = btrfs_get_extent(inode, NULL, 0, 0, (u64)-1, 0);
  292. if (IS_ERR(em)) {
  293. test_msg("Got an error when we shouldn't have\n");
  294. goto out;
  295. }
  296. if (em->block_start != EXTENT_MAP_HOLE) {
  297. test_msg("Expected a hole, got %llu\n", em->block_start);
  298. goto out;
  299. }
  300. if (em->start != 0 || em->len != 5) {
  301. test_msg("Unexpected extent wanted start 0 len 5, got start "
  302. "%llu len %llu\n", em->start, em->len);
  303. goto out;
  304. }
  305. if (em->flags != 0) {
  306. test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
  307. goto out;
  308. }
  309. offset = em->start + em->len;
  310. free_extent_map(em);
  311. em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
  312. if (IS_ERR(em)) {
  313. test_msg("Got an error when we shouldn't have\n");
  314. goto out;
  315. }
  316. if (em->block_start != EXTENT_MAP_INLINE) {
  317. test_msg("Expected an inline, got %llu\n", em->block_start);
  318. goto out;
  319. }
  320. if (em->start != offset || em->len != 4091) {
  321. test_msg("Unexpected extent wanted start %llu len 1, got start "
  322. "%llu len %llu\n", offset, em->start, em->len);
  323. goto out;
  324. }
  325. if (em->flags != 0) {
  326. test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
  327. goto out;
  328. }
  329. /*
  330. * We don't test anything else for inline since it doesn't get set
  331. * unless we have a page for it to write into. Maybe we should change
  332. * this?
  333. */
  334. offset = em->start + em->len;
  335. free_extent_map(em);
  336. em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
  337. if (IS_ERR(em)) {
  338. test_msg("Got an error when we shouldn't have\n");
  339. goto out;
  340. }
  341. if (em->block_start != EXTENT_MAP_HOLE) {
  342. test_msg("Expected a hole, got %llu\n", em->block_start);
  343. goto out;
  344. }
  345. if (em->start != offset || em->len != 4) {
  346. test_msg("Unexpected extent wanted start %llu len 4, got start "
  347. "%llu len %llu\n", offset, em->start, em->len);
  348. goto out;
  349. }
  350. if (em->flags != 0) {
  351. test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
  352. goto out;
  353. }
  354. offset = em->start + em->len;
  355. free_extent_map(em);
  356. /* Regular extent */
  357. em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
  358. if (IS_ERR(em)) {
  359. test_msg("Got an error when we shouldn't have\n");
  360. goto out;
  361. }
  362. if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
  363. test_msg("Expected a real extent, got %llu\n", em->block_start);
  364. goto out;
  365. }
  366. if (em->start != offset || em->len != 4095) {
  367. test_msg("Unexpected extent wanted start %llu len 4095, got "
  368. "start %llu len %llu\n", offset, em->start, em->len);
  369. goto out;
  370. }
  371. if (em->flags != 0) {
  372. test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
  373. goto out;
  374. }
  375. if (em->orig_start != em->start) {
  376. test_msg("Wrong orig offset, want %llu, have %llu\n", em->start,
  377. em->orig_start);
  378. goto out;
  379. }
  380. offset = em->start + em->len;
  381. free_extent_map(em);
  382. /* The next 3 are split extents */
  383. em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
  384. if (IS_ERR(em)) {
  385. test_msg("Got an error when we shouldn't have\n");
  386. goto out;
  387. }
  388. if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
  389. test_msg("Expected a real extent, got %llu\n", em->block_start);
  390. goto out;
  391. }
  392. if (em->start != offset || em->len != 4096) {
  393. test_msg("Unexpected extent wanted start %llu len 4096, got "
  394. "start %llu len %llu\n", offset, em->start, em->len);
  395. goto out;
  396. }
  397. if (em->flags != 0) {
  398. test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
  399. goto out;
  400. }
  401. if (em->orig_start != em->start) {
  402. test_msg("Wrong orig offset, want %llu, have %llu\n", em->start,
  403. em->orig_start);
  404. goto out;
  405. }
  406. disk_bytenr = em->block_start;
  407. orig_start = em->start;
  408. offset = em->start + em->len;
  409. free_extent_map(em);
  410. em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
  411. if (IS_ERR(em)) {
  412. test_msg("Got an error when we shouldn't have\n");
  413. goto out;
  414. }
  415. if (em->block_start != EXTENT_MAP_HOLE) {
  416. test_msg("Expected a hole, got %llu\n", em->block_start);
  417. goto out;
  418. }
  419. if (em->start != offset || em->len != 4096) {
  420. test_msg("Unexpected extent wanted start %llu len 4096, got "
  421. "start %llu len %llu\n", offset, em->start, em->len);
  422. goto out;
  423. }
  424. if (em->flags != 0) {
  425. test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
  426. goto out;
  427. }
  428. offset = em->start + em->len;
  429. free_extent_map(em);
  430. em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
  431. if (IS_ERR(em)) {
  432. test_msg("Got an error when we shouldn't have\n");
  433. goto out;
  434. }
  435. if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
  436. test_msg("Expected a real extent, got %llu\n", em->block_start);
  437. goto out;
  438. }
  439. if (em->start != offset || em->len != 8192) {
  440. test_msg("Unexpected extent wanted start %llu len 8192, got "
  441. "start %llu len %llu\n", offset, em->start, em->len);
  442. goto out;
  443. }
  444. if (em->flags != 0) {
  445. test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
  446. goto out;
  447. }
  448. if (em->orig_start != orig_start) {
  449. test_msg("Wrong orig offset, want %llu, have %llu\n",
  450. orig_start, em->orig_start);
  451. goto out;
  452. }
  453. disk_bytenr += (em->start - orig_start);
  454. if (em->block_start != disk_bytenr) {
  455. test_msg("Wrong block start, want %llu, have %llu\n",
  456. disk_bytenr, em->block_start);
  457. goto out;
  458. }
  459. offset = em->start + em->len;
  460. free_extent_map(em);
  461. /* Prealloc extent */
  462. em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
  463. if (IS_ERR(em)) {
  464. test_msg("Got an error when we shouldn't have\n");
  465. goto out;
  466. }
  467. if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
  468. test_msg("Expected a real extent, got %llu\n", em->block_start);
  469. goto out;
  470. }
  471. if (em->start != offset || em->len != 4096) {
  472. test_msg("Unexpected extent wanted start %llu len 4096, got "
  473. "start %llu len %llu\n", offset, em->start, em->len);
  474. goto out;
  475. }
  476. if (em->flags != prealloc_only) {
  477. test_msg("Unexpected flags set, want %lu have %lu\n",
  478. prealloc_only, em->flags);
  479. goto out;
  480. }
  481. if (em->orig_start != em->start) {
  482. test_msg("Wrong orig offset, want %llu, have %llu\n", em->start,
  483. em->orig_start);
  484. goto out;
  485. }
  486. offset = em->start + em->len;
  487. free_extent_map(em);
  488. /* The next 3 are a half written prealloc extent */
  489. em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
  490. if (IS_ERR(em)) {
  491. test_msg("Got an error when we shouldn't have\n");
  492. goto out;
  493. }
  494. if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
  495. test_msg("Expected a real extent, got %llu\n", em->block_start);
  496. goto out;
  497. }
  498. if (em->start != offset || em->len != 4096) {
  499. test_msg("Unexpected extent wanted start %llu len 4096, got "
  500. "start %llu len %llu\n", offset, em->start, em->len);
  501. goto out;
  502. }
  503. if (em->flags != prealloc_only) {
  504. test_msg("Unexpected flags set, want %lu have %lu\n",
  505. prealloc_only, em->flags);
  506. goto out;
  507. }
  508. if (em->orig_start != em->start) {
  509. test_msg("Wrong orig offset, want %llu, have %llu\n", em->start,
  510. em->orig_start);
  511. goto out;
  512. }
  513. disk_bytenr = em->block_start;
  514. orig_start = em->start;
  515. offset = em->start + em->len;
  516. free_extent_map(em);
  517. em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
  518. if (IS_ERR(em)) {
  519. test_msg("Got an error when we shouldn't have\n");
  520. goto out;
  521. }
  522. if (em->block_start >= EXTENT_MAP_HOLE) {
  523. test_msg("Expected a real extent, got %llu\n", em->block_start);
  524. goto out;
  525. }
  526. if (em->start != offset || em->len != 4096) {
  527. test_msg("Unexpected extent wanted start %llu len 4096, got "
  528. "start %llu len %llu\n", offset, em->start, em->len);
  529. goto out;
  530. }
  531. if (em->flags != 0) {
  532. test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
  533. goto out;
  534. }
  535. if (em->orig_start != orig_start) {
  536. test_msg("Unexpected orig offset, wanted %llu, have %llu\n",
  537. orig_start, em->orig_start);
  538. goto out;
  539. }
  540. if (em->block_start != (disk_bytenr + (em->start - em->orig_start))) {
  541. test_msg("Unexpected block start, wanted %llu, have %llu\n",
  542. disk_bytenr + (em->start - em->orig_start),
  543. em->block_start);
  544. goto out;
  545. }
  546. offset = em->start + em->len;
  547. free_extent_map(em);
  548. em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
  549. if (IS_ERR(em)) {
  550. test_msg("Got an error when we shouldn't have\n");
  551. goto out;
  552. }
  553. if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
  554. test_msg("Expected a real extent, got %llu\n", em->block_start);
  555. goto out;
  556. }
  557. if (em->start != offset || em->len != 8192) {
  558. test_msg("Unexpected extent wanted start %llu len 8192, got "
  559. "start %llu len %llu\n", offset, em->start, em->len);
  560. goto out;
  561. }
  562. if (em->flags != prealloc_only) {
  563. test_msg("Unexpected flags set, want %lu have %lu\n",
  564. prealloc_only, em->flags);
  565. goto out;
  566. }
  567. if (em->orig_start != orig_start) {
  568. test_msg("Wrong orig offset, want %llu, have %llu\n", orig_start,
  569. em->orig_start);
  570. goto out;
  571. }
  572. if (em->block_start != (disk_bytenr + (em->start - em->orig_start))) {
  573. test_msg("Unexpected block start, wanted %llu, have %llu\n",
  574. disk_bytenr + (em->start - em->orig_start),
  575. em->block_start);
  576. goto out;
  577. }
  578. offset = em->start + em->len;
  579. free_extent_map(em);
  580. /* Now for the compressed extent */
  581. em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
  582. if (IS_ERR(em)) {
  583. test_msg("Got an error when we shouldn't have\n");
  584. goto out;
  585. }
  586. if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
  587. test_msg("Expected a real extent, got %llu\n", em->block_start);
  588. goto out;
  589. }
  590. if (em->start != offset || em->len != 8192) {
  591. test_msg("Unexpected extent wanted start %llu len 8192, got "
  592. "start %llu len %llu\n", offset, em->start, em->len);
  593. goto out;
  594. }
  595. if (em->flags != compressed_only) {
  596. test_msg("Unexpected flags set, want %lu have %lu\n",
  597. compressed_only, em->flags);
  598. goto out;
  599. }
  600. if (em->orig_start != em->start) {
  601. test_msg("Wrong orig offset, want %llu, have %llu\n",
  602. em->start, em->orig_start);
  603. goto out;
  604. }
  605. if (em->compress_type != BTRFS_COMPRESS_ZLIB) {
  606. test_msg("Unexpected compress type, wanted %d, got %d\n",
  607. BTRFS_COMPRESS_ZLIB, em->compress_type);
  608. goto out;
  609. }
  610. offset = em->start + em->len;
  611. free_extent_map(em);
  612. /* Split compressed extent */
  613. em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
  614. if (IS_ERR(em)) {
  615. test_msg("Got an error when we shouldn't have\n");
  616. goto out;
  617. }
  618. if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
  619. test_msg("Expected a real extent, got %llu\n", em->block_start);
  620. goto out;
  621. }
  622. if (em->start != offset || em->len != 4096) {
  623. test_msg("Unexpected extent wanted start %llu len 4096, got "
  624. "start %llu len %llu\n", offset, em->start, em->len);
  625. goto out;
  626. }
  627. if (em->flags != compressed_only) {
  628. test_msg("Unexpected flags set, want %lu have %lu\n",
  629. compressed_only, em->flags);
  630. goto out;
  631. }
  632. if (em->orig_start != em->start) {
  633. test_msg("Wrong orig offset, want %llu, have %llu\n",
  634. em->start, em->orig_start);
  635. goto out;
  636. }
  637. if (em->compress_type != BTRFS_COMPRESS_ZLIB) {
  638. test_msg("Unexpected compress type, wanted %d, got %d\n",
  639. BTRFS_COMPRESS_ZLIB, em->compress_type);
  640. goto out;
  641. }
  642. disk_bytenr = em->block_start;
  643. orig_start = em->start;
  644. offset = em->start + em->len;
  645. free_extent_map(em);
  646. em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
  647. if (IS_ERR(em)) {
  648. test_msg("Got an error when we shouldn't have\n");
  649. goto out;
  650. }
  651. if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
  652. test_msg("Expected a real extent, got %llu\n", em->block_start);
  653. goto out;
  654. }
  655. if (em->start != offset || em->len != 4096) {
  656. test_msg("Unexpected extent wanted start %llu len 4096, got "
  657. "start %llu len %llu\n", offset, em->start, em->len);
  658. goto out;
  659. }
  660. if (em->flags != 0) {
  661. test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
  662. goto out;
  663. }
  664. if (em->orig_start != em->start) {
  665. test_msg("Wrong orig offset, want %llu, have %llu\n", em->start,
  666. em->orig_start);
  667. goto out;
  668. }
  669. offset = em->start + em->len;
  670. free_extent_map(em);
  671. em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
  672. if (IS_ERR(em)) {
  673. test_msg("Got an error when we shouldn't have\n");
  674. goto out;
  675. }
  676. if (em->block_start != disk_bytenr) {
  677. test_msg("Block start does not match, want %llu got %llu\n",
  678. disk_bytenr, em->block_start);
  679. goto out;
  680. }
  681. if (em->start != offset || em->len != 8192) {
  682. test_msg("Unexpected extent wanted start %llu len 8192, got "
  683. "start %llu len %llu\n", offset, em->start, em->len);
  684. goto out;
  685. }
  686. if (em->flags != compressed_only) {
  687. test_msg("Unexpected flags set, want %lu have %lu\n",
  688. compressed_only, em->flags);
  689. goto out;
  690. }
  691. if (em->orig_start != orig_start) {
  692. test_msg("Wrong orig offset, want %llu, have %llu\n",
  693. em->start, orig_start);
  694. goto out;
  695. }
  696. if (em->compress_type != BTRFS_COMPRESS_ZLIB) {
  697. test_msg("Unexpected compress type, wanted %d, got %d\n",
  698. BTRFS_COMPRESS_ZLIB, em->compress_type);
  699. goto out;
  700. }
  701. offset = em->start + em->len;
  702. free_extent_map(em);
  703. /* A hole between regular extents but no hole extent */
  704. em = btrfs_get_extent(inode, NULL, 0, offset + 6, 4096, 0);
  705. if (IS_ERR(em)) {
  706. test_msg("Got an error when we shouldn't have\n");
  707. goto out;
  708. }
  709. if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
  710. test_msg("Expected a real extent, got %llu\n", em->block_start);
  711. goto out;
  712. }
  713. if (em->start != offset || em->len != 4096) {
  714. test_msg("Unexpected extent wanted start %llu len 4096, got "
  715. "start %llu len %llu\n", offset, em->start, em->len);
  716. goto out;
  717. }
  718. if (em->flags != 0) {
  719. test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
  720. goto out;
  721. }
  722. if (em->orig_start != em->start) {
  723. test_msg("Wrong orig offset, want %llu, have %llu\n", em->start,
  724. em->orig_start);
  725. goto out;
  726. }
  727. offset = em->start + em->len;
  728. free_extent_map(em);
  729. em = btrfs_get_extent(inode, NULL, 0, offset, 4096 * 1024, 0);
  730. if (IS_ERR(em)) {
  731. test_msg("Got an error when we shouldn't have\n");
  732. goto out;
  733. }
  734. if (em->block_start != EXTENT_MAP_HOLE) {
  735. test_msg("Expected a hole extent, got %llu\n", em->block_start);
  736. goto out;
  737. }
  738. /*
  739. * Currently we just return a length that we requested rather than the
  740. * length of the actual hole, if this changes we'll have to change this
  741. * test.
  742. */
  743. if (em->start != offset || em->len != 12288) {
  744. test_msg("Unexpected extent wanted start %llu len 12288, got "
  745. "start %llu len %llu\n", offset, em->start, em->len);
  746. goto out;
  747. }
  748. if (em->flags != vacancy_only) {
  749. test_msg("Unexpected flags set, want %lu have %lu\n",
  750. vacancy_only, em->flags);
  751. goto out;
  752. }
  753. if (em->orig_start != em->start) {
  754. test_msg("Wrong orig offset, want %llu, have %llu\n", em->start,
  755. em->orig_start);
  756. goto out;
  757. }
  758. offset = em->start + em->len;
  759. free_extent_map(em);
  760. em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0);
  761. if (IS_ERR(em)) {
  762. test_msg("Got an error when we shouldn't have\n");
  763. goto out;
  764. }
  765. if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
  766. test_msg("Expected a real extent, got %llu\n", em->block_start);
  767. goto out;
  768. }
  769. if (em->start != offset || em->len != 4096) {
  770. test_msg("Unexpected extent wanted start %llu len 4096, got "
  771. "start %llu len %llu\n", offset, em->start, em->len);
  772. goto out;
  773. }
  774. if (em->flags != 0) {
  775. test_msg("Unexpected flags set, want 0 have %lu\n", em->flags);
  776. goto out;
  777. }
  778. if (em->orig_start != em->start) {
  779. test_msg("Wrong orig offset, want %llu, have %llu\n", em->start,
  780. em->orig_start);
  781. goto out;
  782. }
  783. ret = 0;
  784. out:
  785. if (!IS_ERR(em))
  786. free_extent_map(em);
  787. iput(inode);
  788. free_dummy_root(root);
  789. return ret;
  790. }
  791. static int test_hole_first(void)
  792. {
  793. struct inode *inode = NULL;
  794. struct btrfs_root *root = NULL;
  795. struct extent_map *em = NULL;
  796. int ret = -ENOMEM;
  797. inode = btrfs_new_test_inode();
  798. if (!inode) {
  799. test_msg("Couldn't allocate inode\n");
  800. return ret;
  801. }
  802. BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY;
  803. BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID;
  804. BTRFS_I(inode)->location.offset = 0;
  805. root = btrfs_alloc_dummy_root();
  806. if (IS_ERR(root)) {
  807. test_msg("Couldn't allocate root\n");
  808. goto out;
  809. }
  810. root->fs_info = alloc_dummy_fs_info();
  811. if (!root->fs_info) {
  812. test_msg("Couldn't allocate dummy fs info\n");
  813. goto out;
  814. }
  815. root->node = alloc_dummy_extent_buffer(0, 4096);
  816. if (!root->node) {
  817. test_msg("Couldn't allocate dummy buffer\n");
  818. goto out;
  819. }
  820. extent_buffer_get(root->node);
  821. btrfs_set_header_nritems(root->node, 0);
  822. btrfs_set_header_level(root->node, 0);
  823. BTRFS_I(inode)->root = root;
  824. ret = -EINVAL;
  825. /*
  826. * Need a blank inode item here just so we don't confuse
  827. * btrfs_get_extent.
  828. */
  829. insert_inode_item_key(root);
  830. insert_extent(root, 4096, 4096, 4096, 0, 4096, 4096,
  831. BTRFS_FILE_EXTENT_REG, 0, 1);
  832. em = btrfs_get_extent(inode, NULL, 0, 0, 8192, 0);
  833. if (IS_ERR(em)) {
  834. test_msg("Got an error when we shouldn't have\n");
  835. goto out;
  836. }
  837. if (em->block_start != EXTENT_MAP_HOLE) {
  838. test_msg("Expected a hole, got %llu\n", em->block_start);
  839. goto out;
  840. }
  841. if (em->start != 0 || em->len != 4096) {
  842. test_msg("Unexpected extent wanted start 0 len 4096, got start "
  843. "%llu len %llu\n", em->start, em->len);
  844. goto out;
  845. }
  846. if (em->flags != vacancy_only) {
  847. test_msg("Wrong flags, wanted %lu, have %lu\n", vacancy_only,
  848. em->flags);
  849. goto out;
  850. }
  851. free_extent_map(em);
  852. em = btrfs_get_extent(inode, NULL, 0, 4096, 8192, 0);
  853. if (IS_ERR(em)) {
  854. test_msg("Got an error when we shouldn't have\n");
  855. goto out;
  856. }
  857. if (em->block_start != 4096) {
  858. test_msg("Expected a real extent, got %llu\n", em->block_start);
  859. goto out;
  860. }
  861. if (em->start != 4096 || em->len != 4096) {
  862. test_msg("Unexpected extent wanted start 4096 len 4096, got "
  863. "start %llu len %llu\n", em->start, em->len);
  864. goto out;
  865. }
  866. if (em->flags != 0) {
  867. test_msg("Unexpected flags set, wanted 0 got %lu\n",
  868. em->flags);
  869. goto out;
  870. }
  871. ret = 0;
  872. out:
  873. if (!IS_ERR(em))
  874. free_extent_map(em);
  875. iput(inode);
  876. free_dummy_root(root);
  877. return ret;
  878. }
  879. int btrfs_test_inodes(void)
  880. {
  881. int ret;
  882. set_bit(EXTENT_FLAG_COMPRESSED, &compressed_only);
  883. set_bit(EXTENT_FLAG_VACANCY, &vacancy_only);
  884. set_bit(EXTENT_FLAG_PREALLOC, &prealloc_only);
  885. test_msg("Running btrfs_get_extent tests\n");
  886. ret = test_btrfs_get_extent();
  887. if (ret)
  888. return ret;
  889. test_msg("Running hole first btrfs_get_extent test\n");
  890. return test_hole_first();
  891. }