xfs_btree.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  1. /*
  2. * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
  3. * All Rights Reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it would be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write the Free Software Foundation,
  16. * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include "xfs.h"
  19. #include "xfs_fs.h"
  20. #include "xfs_types.h"
  21. #include "xfs_bit.h"
  22. #include "xfs_log.h"
  23. #include "xfs_inum.h"
  24. #include "xfs_trans.h"
  25. #include "xfs_sb.h"
  26. #include "xfs_ag.h"
  27. #include "xfs_dir2.h"
  28. #include "xfs_dmapi.h"
  29. #include "xfs_mount.h"
  30. #include "xfs_bmap_btree.h"
  31. #include "xfs_alloc_btree.h"
  32. #include "xfs_ialloc_btree.h"
  33. #include "xfs_dir2_sf.h"
  34. #include "xfs_attr_sf.h"
  35. #include "xfs_dinode.h"
  36. #include "xfs_inode.h"
  37. #include "xfs_btree.h"
  38. #include "xfs_ialloc.h"
  39. #include "xfs_error.h"
  40. /*
  41. * Cursor allocation zone.
  42. */
  43. kmem_zone_t *xfs_btree_cur_zone;
  44. /*
  45. * Btree magic numbers.
  46. */
  47. const __uint32_t xfs_magics[XFS_BTNUM_MAX] = {
  48. XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, XFS_BMAP_MAGIC, XFS_IBT_MAGIC
  49. };
  50. /*
  51. * Checking routine: return maxrecs for the block.
  52. */
  53. STATIC int /* number of records fitting in block */
  54. xfs_btree_maxrecs(
  55. xfs_btree_cur_t *cur, /* btree cursor */
  56. xfs_btree_block_t *block) /* generic btree block pointer */
  57. {
  58. switch (cur->bc_btnum) {
  59. case XFS_BTNUM_BNO:
  60. case XFS_BTNUM_CNT:
  61. return (int)XFS_ALLOC_BLOCK_MAXRECS(
  62. be16_to_cpu(block->bb_level), cur);
  63. case XFS_BTNUM_BMAP:
  64. return (int)XFS_BMAP_BLOCK_IMAXRECS(
  65. be16_to_cpu(block->bb_level), cur);
  66. case XFS_BTNUM_INO:
  67. return (int)XFS_INOBT_BLOCK_MAXRECS(
  68. be16_to_cpu(block->bb_level), cur);
  69. default:
  70. ASSERT(0);
  71. return 0;
  72. }
  73. }
  74. /*
  75. * External routines.
  76. */
  77. #ifdef DEBUG
  78. /*
  79. * Debug routine: check that block header is ok.
  80. */
  81. void
  82. xfs_btree_check_block(
  83. xfs_btree_cur_t *cur, /* btree cursor */
  84. xfs_btree_block_t *block, /* generic btree block pointer */
  85. int level, /* level of the btree block */
  86. xfs_buf_t *bp) /* buffer containing block, if any */
  87. {
  88. if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
  89. xfs_btree_check_lblock(cur, (xfs_btree_lblock_t *)block, level,
  90. bp);
  91. else
  92. xfs_btree_check_sblock(cur, (xfs_btree_sblock_t *)block, level,
  93. bp);
  94. }
  95. /*
  96. * Debug routine: check that keys are in the right order.
  97. */
  98. void
  99. xfs_btree_check_key(
  100. xfs_btnum_t btnum, /* btree identifier */
  101. void *ak1, /* pointer to left (lower) key */
  102. void *ak2) /* pointer to right (higher) key */
  103. {
  104. switch (btnum) {
  105. case XFS_BTNUM_BNO: {
  106. xfs_alloc_key_t *k1;
  107. xfs_alloc_key_t *k2;
  108. k1 = ak1;
  109. k2 = ak2;
  110. ASSERT(be32_to_cpu(k1->ar_startblock) < be32_to_cpu(k2->ar_startblock));
  111. break;
  112. }
  113. case XFS_BTNUM_CNT: {
  114. xfs_alloc_key_t *k1;
  115. xfs_alloc_key_t *k2;
  116. k1 = ak1;
  117. k2 = ak2;
  118. ASSERT(be32_to_cpu(k1->ar_blockcount) < be32_to_cpu(k2->ar_blockcount) ||
  119. (k1->ar_blockcount == k2->ar_blockcount &&
  120. be32_to_cpu(k1->ar_startblock) < be32_to_cpu(k2->ar_startblock)));
  121. break;
  122. }
  123. case XFS_BTNUM_BMAP: {
  124. xfs_bmbt_key_t *k1;
  125. xfs_bmbt_key_t *k2;
  126. k1 = ak1;
  127. k2 = ak2;
  128. ASSERT(be64_to_cpu(k1->br_startoff) < be64_to_cpu(k2->br_startoff));
  129. break;
  130. }
  131. case XFS_BTNUM_INO: {
  132. xfs_inobt_key_t *k1;
  133. xfs_inobt_key_t *k2;
  134. k1 = ak1;
  135. k2 = ak2;
  136. ASSERT(be32_to_cpu(k1->ir_startino) < be32_to_cpu(k2->ir_startino));
  137. break;
  138. }
  139. default:
  140. ASSERT(0);
  141. }
  142. }
  143. #endif /* DEBUG */
  144. /*
  145. * Checking routine: check that long form block header is ok.
  146. */
  147. /* ARGSUSED */
  148. int /* error (0 or EFSCORRUPTED) */
  149. xfs_btree_check_lblock(
  150. xfs_btree_cur_t *cur, /* btree cursor */
  151. xfs_btree_lblock_t *block, /* btree long form block pointer */
  152. int level, /* level of the btree block */
  153. xfs_buf_t *bp) /* buffer for block, if any */
  154. {
  155. int lblock_ok; /* block passes checks */
  156. xfs_mount_t *mp; /* file system mount point */
  157. mp = cur->bc_mp;
  158. lblock_ok =
  159. be32_to_cpu(block->bb_magic) == xfs_magics[cur->bc_btnum] &&
  160. be16_to_cpu(block->bb_level) == level &&
  161. be16_to_cpu(block->bb_numrecs) <=
  162. xfs_btree_maxrecs(cur, (xfs_btree_block_t *)block) &&
  163. block->bb_leftsib &&
  164. (be64_to_cpu(block->bb_leftsib) == NULLDFSBNO ||
  165. XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_leftsib))) &&
  166. block->bb_rightsib &&
  167. (be64_to_cpu(block->bb_rightsib) == NULLDFSBNO ||
  168. XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_rightsib)));
  169. if (unlikely(XFS_TEST_ERROR(!lblock_ok, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK,
  170. XFS_RANDOM_BTREE_CHECK_LBLOCK))) {
  171. if (bp)
  172. xfs_buftrace("LBTREE ERROR", bp);
  173. XFS_ERROR_REPORT("xfs_btree_check_lblock", XFS_ERRLEVEL_LOW,
  174. mp);
  175. return XFS_ERROR(EFSCORRUPTED);
  176. }
  177. return 0;
  178. }
  179. /*
  180. * Checking routine: check that (long) pointer is ok.
  181. */
  182. int /* error (0 or EFSCORRUPTED) */
  183. xfs_btree_check_lptr(
  184. xfs_btree_cur_t *cur, /* btree cursor */
  185. xfs_dfsbno_t ptr, /* btree block disk address */
  186. int level) /* btree block level */
  187. {
  188. xfs_mount_t *mp; /* file system mount point */
  189. mp = cur->bc_mp;
  190. XFS_WANT_CORRUPTED_RETURN(
  191. level > 0 &&
  192. ptr != NULLDFSBNO &&
  193. XFS_FSB_SANITY_CHECK(mp, ptr));
  194. return 0;
  195. }
  196. #ifdef DEBUG
  197. /*
  198. * Debug routine: check that records are in the right order.
  199. */
  200. void
  201. xfs_btree_check_rec(
  202. xfs_btnum_t btnum, /* btree identifier */
  203. void *ar1, /* pointer to left (lower) record */
  204. void *ar2) /* pointer to right (higher) record */
  205. {
  206. switch (btnum) {
  207. case XFS_BTNUM_BNO: {
  208. xfs_alloc_rec_t *r1;
  209. xfs_alloc_rec_t *r2;
  210. r1 = ar1;
  211. r2 = ar2;
  212. ASSERT(be32_to_cpu(r1->ar_startblock) +
  213. be32_to_cpu(r1->ar_blockcount) <=
  214. be32_to_cpu(r2->ar_startblock));
  215. break;
  216. }
  217. case XFS_BTNUM_CNT: {
  218. xfs_alloc_rec_t *r1;
  219. xfs_alloc_rec_t *r2;
  220. r1 = ar1;
  221. r2 = ar2;
  222. ASSERT(be32_to_cpu(r1->ar_blockcount) < be32_to_cpu(r2->ar_blockcount) ||
  223. (r1->ar_blockcount == r2->ar_blockcount &&
  224. be32_to_cpu(r1->ar_startblock) < be32_to_cpu(r2->ar_startblock)));
  225. break;
  226. }
  227. case XFS_BTNUM_BMAP: {
  228. xfs_bmbt_rec_t *r1;
  229. xfs_bmbt_rec_t *r2;
  230. r1 = ar1;
  231. r2 = ar2;
  232. ASSERT(xfs_bmbt_disk_get_startoff(r1) +
  233. xfs_bmbt_disk_get_blockcount(r1) <=
  234. xfs_bmbt_disk_get_startoff(r2));
  235. break;
  236. }
  237. case XFS_BTNUM_INO: {
  238. xfs_inobt_rec_t *r1;
  239. xfs_inobt_rec_t *r2;
  240. r1 = ar1;
  241. r2 = ar2;
  242. ASSERT(be32_to_cpu(r1->ir_startino) + XFS_INODES_PER_CHUNK <=
  243. be32_to_cpu(r2->ir_startino));
  244. break;
  245. }
  246. default:
  247. ASSERT(0);
  248. }
  249. }
  250. #endif /* DEBUG */
  251. /*
  252. * Checking routine: check that block header is ok.
  253. */
  254. /* ARGSUSED */
  255. int /* error (0 or EFSCORRUPTED) */
  256. xfs_btree_check_sblock(
  257. xfs_btree_cur_t *cur, /* btree cursor */
  258. xfs_btree_sblock_t *block, /* btree short form block pointer */
  259. int level, /* level of the btree block */
  260. xfs_buf_t *bp) /* buffer containing block */
  261. {
  262. xfs_buf_t *agbp; /* buffer for ag. freespace struct */
  263. xfs_agf_t *agf; /* ag. freespace structure */
  264. xfs_agblock_t agflen; /* native ag. freespace length */
  265. int sblock_ok; /* block passes checks */
  266. agbp = cur->bc_private.a.agbp;
  267. agf = XFS_BUF_TO_AGF(agbp);
  268. agflen = be32_to_cpu(agf->agf_length);
  269. sblock_ok =
  270. be32_to_cpu(block->bb_magic) == xfs_magics[cur->bc_btnum] &&
  271. be16_to_cpu(block->bb_level) == level &&
  272. be16_to_cpu(block->bb_numrecs) <=
  273. xfs_btree_maxrecs(cur, (xfs_btree_block_t *)block) &&
  274. (be32_to_cpu(block->bb_leftsib) == NULLAGBLOCK ||
  275. be32_to_cpu(block->bb_leftsib) < agflen) &&
  276. block->bb_leftsib &&
  277. (be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK ||
  278. be32_to_cpu(block->bb_rightsib) < agflen) &&
  279. block->bb_rightsib;
  280. if (unlikely(XFS_TEST_ERROR(!sblock_ok, cur->bc_mp,
  281. XFS_ERRTAG_BTREE_CHECK_SBLOCK,
  282. XFS_RANDOM_BTREE_CHECK_SBLOCK))) {
  283. if (bp)
  284. xfs_buftrace("SBTREE ERROR", bp);
  285. XFS_ERROR_REPORT("xfs_btree_check_sblock", XFS_ERRLEVEL_LOW,
  286. cur->bc_mp);
  287. return XFS_ERROR(EFSCORRUPTED);
  288. }
  289. return 0;
  290. }
  291. /*
  292. * Checking routine: check that (short) pointer is ok.
  293. */
  294. int /* error (0 or EFSCORRUPTED) */
  295. xfs_btree_check_sptr(
  296. xfs_btree_cur_t *cur, /* btree cursor */
  297. xfs_agblock_t ptr, /* btree block disk address */
  298. int level) /* btree block level */
  299. {
  300. xfs_buf_t *agbp; /* buffer for ag. freespace struct */
  301. xfs_agf_t *agf; /* ag. freespace structure */
  302. agbp = cur->bc_private.a.agbp;
  303. agf = XFS_BUF_TO_AGF(agbp);
  304. XFS_WANT_CORRUPTED_RETURN(
  305. level > 0 &&
  306. ptr != NULLAGBLOCK && ptr != 0 &&
  307. ptr < be32_to_cpu(agf->agf_length));
  308. return 0;
  309. }
  310. /*
  311. * Delete the btree cursor.
  312. */
  313. void
  314. xfs_btree_del_cursor(
  315. xfs_btree_cur_t *cur, /* btree cursor */
  316. int error) /* del because of error */
  317. {
  318. int i; /* btree level */
  319. /*
  320. * Clear the buffer pointers, and release the buffers.
  321. * If we're doing this in the face of an error, we
  322. * need to make sure to inspect all of the entries
  323. * in the bc_bufs array for buffers to be unlocked.
  324. * This is because some of the btree code works from
  325. * level n down to 0, and if we get an error along
  326. * the way we won't have initialized all the entries
  327. * down to 0.
  328. */
  329. for (i = 0; i < cur->bc_nlevels; i++) {
  330. if (cur->bc_bufs[i])
  331. xfs_btree_setbuf(cur, i, NULL);
  332. else if (!error)
  333. break;
  334. }
  335. /*
  336. * Can't free a bmap cursor without having dealt with the
  337. * allocated indirect blocks' accounting.
  338. */
  339. ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP ||
  340. cur->bc_private.b.allocated == 0);
  341. /*
  342. * Free the cursor.
  343. */
  344. kmem_zone_free(xfs_btree_cur_zone, cur);
  345. }
  346. /*
  347. * Duplicate the btree cursor.
  348. * Allocate a new one, copy the record, re-get the buffers.
  349. */
  350. int /* error */
  351. xfs_btree_dup_cursor(
  352. xfs_btree_cur_t *cur, /* input cursor */
  353. xfs_btree_cur_t **ncur) /* output cursor */
  354. {
  355. xfs_buf_t *bp; /* btree block's buffer pointer */
  356. int error; /* error return value */
  357. int i; /* level number of btree block */
  358. xfs_mount_t *mp; /* mount structure for filesystem */
  359. xfs_btree_cur_t *new; /* new cursor value */
  360. xfs_trans_t *tp; /* transaction pointer, can be NULL */
  361. tp = cur->bc_tp;
  362. mp = cur->bc_mp;
  363. /*
  364. * Allocate a new cursor like the old one.
  365. */
  366. new = cur->bc_ops->dup_cursor(cur);
  367. /*
  368. * Copy the record currently in the cursor.
  369. */
  370. new->bc_rec = cur->bc_rec;
  371. /*
  372. * For each level current, re-get the buffer and copy the ptr value.
  373. */
  374. for (i = 0; i < new->bc_nlevels; i++) {
  375. new->bc_ptrs[i] = cur->bc_ptrs[i];
  376. new->bc_ra[i] = cur->bc_ra[i];
  377. if ((bp = cur->bc_bufs[i])) {
  378. if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
  379. XFS_BUF_ADDR(bp), mp->m_bsize, 0, &bp))) {
  380. xfs_btree_del_cursor(new, error);
  381. *ncur = NULL;
  382. return error;
  383. }
  384. new->bc_bufs[i] = bp;
  385. ASSERT(bp);
  386. ASSERT(!XFS_BUF_GETERROR(bp));
  387. } else
  388. new->bc_bufs[i] = NULL;
  389. }
  390. *ncur = new;
  391. return 0;
  392. }
  393. /*
  394. * Get a the root block which is stored in the inode.
  395. *
  396. * For now this btree implementation assumes the btree root is always
  397. * stored in the if_broot field of an inode fork.
  398. */
  399. STATIC struct xfs_btree_block *
  400. xfs_btree_get_iroot(
  401. struct xfs_btree_cur *cur)
  402. {
  403. struct xfs_ifork *ifp;
  404. ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, cur->bc_private.b.whichfork);
  405. return (struct xfs_btree_block *)ifp->if_broot;
  406. }
  407. /*
  408. * Retrieve the block pointer from the cursor at the given level.
  409. * This may be an inode btree root or from a buffer.
  410. */
  411. STATIC struct xfs_btree_block * /* generic btree block pointer */
  412. xfs_btree_get_block(
  413. struct xfs_btree_cur *cur, /* btree cursor */
  414. int level, /* level in btree */
  415. struct xfs_buf **bpp) /* buffer containing the block */
  416. {
  417. if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
  418. (level == cur->bc_nlevels - 1)) {
  419. *bpp = NULL;
  420. return xfs_btree_get_iroot(cur);
  421. }
  422. *bpp = cur->bc_bufs[level];
  423. return XFS_BUF_TO_BLOCK(*bpp);
  424. }
  425. /*
  426. * Get a buffer for the block, return it with no data read.
  427. * Long-form addressing.
  428. */
  429. xfs_buf_t * /* buffer for fsbno */
  430. xfs_btree_get_bufl(
  431. xfs_mount_t *mp, /* file system mount point */
  432. xfs_trans_t *tp, /* transaction pointer */
  433. xfs_fsblock_t fsbno, /* file system block number */
  434. uint lock) /* lock flags for get_buf */
  435. {
  436. xfs_buf_t *bp; /* buffer pointer (return value) */
  437. xfs_daddr_t d; /* real disk block address */
  438. ASSERT(fsbno != NULLFSBLOCK);
  439. d = XFS_FSB_TO_DADDR(mp, fsbno);
  440. bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock);
  441. ASSERT(bp);
  442. ASSERT(!XFS_BUF_GETERROR(bp));
  443. return bp;
  444. }
  445. /*
  446. * Get a buffer for the block, return it with no data read.
  447. * Short-form addressing.
  448. */
  449. xfs_buf_t * /* buffer for agno/agbno */
  450. xfs_btree_get_bufs(
  451. xfs_mount_t *mp, /* file system mount point */
  452. xfs_trans_t *tp, /* transaction pointer */
  453. xfs_agnumber_t agno, /* allocation group number */
  454. xfs_agblock_t agbno, /* allocation group block number */
  455. uint lock) /* lock flags for get_buf */
  456. {
  457. xfs_buf_t *bp; /* buffer pointer (return value) */
  458. xfs_daddr_t d; /* real disk block address */
  459. ASSERT(agno != NULLAGNUMBER);
  460. ASSERT(agbno != NULLAGBLOCK);
  461. d = XFS_AGB_TO_DADDR(mp, agno, agbno);
  462. bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock);
  463. ASSERT(bp);
  464. ASSERT(!XFS_BUF_GETERROR(bp));
  465. return bp;
  466. }
  467. /*
  468. * Check for the cursor referring to the last block at the given level.
  469. */
  470. int /* 1=is last block, 0=not last block */
  471. xfs_btree_islastblock(
  472. xfs_btree_cur_t *cur, /* btree cursor */
  473. int level) /* level to check */
  474. {
  475. xfs_btree_block_t *block; /* generic btree block pointer */
  476. xfs_buf_t *bp; /* buffer containing block */
  477. block = xfs_btree_get_block(cur, level, &bp);
  478. xfs_btree_check_block(cur, block, level, bp);
  479. if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
  480. return be64_to_cpu(block->bb_u.l.bb_rightsib) == NULLDFSBNO;
  481. else
  482. return be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK;
  483. }
  484. /*
  485. * Change the cursor to point to the first record at the given level.
  486. * Other levels are unaffected.
  487. */
  488. int /* success=1, failure=0 */
  489. xfs_btree_firstrec(
  490. xfs_btree_cur_t *cur, /* btree cursor */
  491. int level) /* level to change */
  492. {
  493. xfs_btree_block_t *block; /* generic btree block pointer */
  494. xfs_buf_t *bp; /* buffer containing block */
  495. /*
  496. * Get the block pointer for this level.
  497. */
  498. block = xfs_btree_get_block(cur, level, &bp);
  499. xfs_btree_check_block(cur, block, level, bp);
  500. /*
  501. * It's empty, there is no such record.
  502. */
  503. if (!block->bb_numrecs)
  504. return 0;
  505. /*
  506. * Set the ptr value to 1, that's the first record/key.
  507. */
  508. cur->bc_ptrs[level] = 1;
  509. return 1;
  510. }
  511. /*
  512. * Change the cursor to point to the last record in the current block
  513. * at the given level. Other levels are unaffected.
  514. */
  515. int /* success=1, failure=0 */
  516. xfs_btree_lastrec(
  517. xfs_btree_cur_t *cur, /* btree cursor */
  518. int level) /* level to change */
  519. {
  520. xfs_btree_block_t *block; /* generic btree block pointer */
  521. xfs_buf_t *bp; /* buffer containing block */
  522. /*
  523. * Get the block pointer for this level.
  524. */
  525. block = xfs_btree_get_block(cur, level, &bp);
  526. xfs_btree_check_block(cur, block, level, bp);
  527. /*
  528. * It's empty, there is no such record.
  529. */
  530. if (!block->bb_numrecs)
  531. return 0;
  532. /*
  533. * Set the ptr value to numrecs, that's the last record/key.
  534. */
  535. cur->bc_ptrs[level] = be16_to_cpu(block->bb_numrecs);
  536. return 1;
  537. }
  538. /*
  539. * Compute first and last byte offsets for the fields given.
  540. * Interprets the offsets table, which contains struct field offsets.
  541. */
  542. void
  543. xfs_btree_offsets(
  544. __int64_t fields, /* bitmask of fields */
  545. const short *offsets, /* table of field offsets */
  546. int nbits, /* number of bits to inspect */
  547. int *first, /* output: first byte offset */
  548. int *last) /* output: last byte offset */
  549. {
  550. int i; /* current bit number */
  551. __int64_t imask; /* mask for current bit number */
  552. ASSERT(fields != 0);
  553. /*
  554. * Find the lowest bit, so the first byte offset.
  555. */
  556. for (i = 0, imask = 1LL; ; i++, imask <<= 1) {
  557. if (imask & fields) {
  558. *first = offsets[i];
  559. break;
  560. }
  561. }
  562. /*
  563. * Find the highest bit, so the last byte offset.
  564. */
  565. for (i = nbits - 1, imask = 1LL << i; ; i--, imask >>= 1) {
  566. if (imask & fields) {
  567. *last = offsets[i + 1] - 1;
  568. break;
  569. }
  570. }
  571. }
  572. /*
  573. * Get a buffer for the block, return it read in.
  574. * Long-form addressing.
  575. */
  576. int /* error */
  577. xfs_btree_read_bufl(
  578. xfs_mount_t *mp, /* file system mount point */
  579. xfs_trans_t *tp, /* transaction pointer */
  580. xfs_fsblock_t fsbno, /* file system block number */
  581. uint lock, /* lock flags for read_buf */
  582. xfs_buf_t **bpp, /* buffer for fsbno */
  583. int refval) /* ref count value for buffer */
  584. {
  585. xfs_buf_t *bp; /* return value */
  586. xfs_daddr_t d; /* real disk block address */
  587. int error;
  588. ASSERT(fsbno != NULLFSBLOCK);
  589. d = XFS_FSB_TO_DADDR(mp, fsbno);
  590. if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
  591. mp->m_bsize, lock, &bp))) {
  592. return error;
  593. }
  594. ASSERT(!bp || !XFS_BUF_GETERROR(bp));
  595. if (bp != NULL) {
  596. XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval);
  597. }
  598. *bpp = bp;
  599. return 0;
  600. }
  601. /*
  602. * Get a buffer for the block, return it read in.
  603. * Short-form addressing.
  604. */
  605. int /* error */
  606. xfs_btree_read_bufs(
  607. xfs_mount_t *mp, /* file system mount point */
  608. xfs_trans_t *tp, /* transaction pointer */
  609. xfs_agnumber_t agno, /* allocation group number */
  610. xfs_agblock_t agbno, /* allocation group block number */
  611. uint lock, /* lock flags for read_buf */
  612. xfs_buf_t **bpp, /* buffer for agno/agbno */
  613. int refval) /* ref count value for buffer */
  614. {
  615. xfs_buf_t *bp; /* return value */
  616. xfs_daddr_t d; /* real disk block address */
  617. int error;
  618. ASSERT(agno != NULLAGNUMBER);
  619. ASSERT(agbno != NULLAGBLOCK);
  620. d = XFS_AGB_TO_DADDR(mp, agno, agbno);
  621. if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
  622. mp->m_bsize, lock, &bp))) {
  623. return error;
  624. }
  625. ASSERT(!bp || !XFS_BUF_GETERROR(bp));
  626. if (bp != NULL) {
  627. switch (refval) {
  628. case XFS_ALLOC_BTREE_REF:
  629. XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval);
  630. break;
  631. case XFS_INO_BTREE_REF:
  632. XFS_BUF_SET_VTYPE_REF(bp, B_FS_INOMAP, refval);
  633. break;
  634. }
  635. }
  636. *bpp = bp;
  637. return 0;
  638. }
  639. /*
  640. * Read-ahead the block, don't wait for it, don't return a buffer.
  641. * Long-form addressing.
  642. */
  643. /* ARGSUSED */
  644. void
  645. xfs_btree_reada_bufl(
  646. xfs_mount_t *mp, /* file system mount point */
  647. xfs_fsblock_t fsbno, /* file system block number */
  648. xfs_extlen_t count) /* count of filesystem blocks */
  649. {
  650. xfs_daddr_t d;
  651. ASSERT(fsbno != NULLFSBLOCK);
  652. d = XFS_FSB_TO_DADDR(mp, fsbno);
  653. xfs_baread(mp->m_ddev_targp, d, mp->m_bsize * count);
  654. }
  655. /*
  656. * Read-ahead the block, don't wait for it, don't return a buffer.
  657. * Short-form addressing.
  658. */
  659. /* ARGSUSED */
  660. void
  661. xfs_btree_reada_bufs(
  662. xfs_mount_t *mp, /* file system mount point */
  663. xfs_agnumber_t agno, /* allocation group number */
  664. xfs_agblock_t agbno, /* allocation group block number */
  665. xfs_extlen_t count) /* count of filesystem blocks */
  666. {
  667. xfs_daddr_t d;
  668. ASSERT(agno != NULLAGNUMBER);
  669. ASSERT(agbno != NULLAGBLOCK);
  670. d = XFS_AGB_TO_DADDR(mp, agno, agbno);
  671. xfs_baread(mp->m_ddev_targp, d, mp->m_bsize * count);
  672. }
  673. STATIC int
  674. xfs_btree_readahead_lblock(
  675. struct xfs_btree_cur *cur,
  676. int lr,
  677. struct xfs_btree_block *block)
  678. {
  679. int rval = 0;
  680. xfs_fsblock_t left = be64_to_cpu(block->bb_u.l.bb_leftsib);
  681. xfs_fsblock_t right = be64_to_cpu(block->bb_u.l.bb_rightsib);
  682. if ((lr & XFS_BTCUR_LEFTRA) && left != NULLDFSBNO) {
  683. xfs_btree_reada_bufl(cur->bc_mp, left, 1);
  684. rval++;
  685. }
  686. if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLDFSBNO) {
  687. xfs_btree_reada_bufl(cur->bc_mp, right, 1);
  688. rval++;
  689. }
  690. return rval;
  691. }
  692. STATIC int
  693. xfs_btree_readahead_sblock(
  694. struct xfs_btree_cur *cur,
  695. int lr,
  696. struct xfs_btree_block *block)
  697. {
  698. int rval = 0;
  699. xfs_agblock_t left = be32_to_cpu(block->bb_u.s.bb_leftsib);
  700. xfs_agblock_t right = be32_to_cpu(block->bb_u.s.bb_rightsib);
  701. if ((lr & XFS_BTCUR_LEFTRA) && left != NULLAGBLOCK) {
  702. xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno,
  703. left, 1);
  704. rval++;
  705. }
  706. if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLAGBLOCK) {
  707. xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno,
  708. right, 1);
  709. rval++;
  710. }
  711. return rval;
  712. }
  713. /*
  714. * Read-ahead btree blocks, at the given level.
  715. * Bits in lr are set from XFS_BTCUR_{LEFT,RIGHT}RA.
  716. */
  717. int
  718. xfs_btree_readahead(
  719. struct xfs_btree_cur *cur, /* btree cursor */
  720. int lev, /* level in btree */
  721. int lr) /* left/right bits */
  722. {
  723. struct xfs_btree_block *block;
  724. /*
  725. * No readahead needed if we are at the root level and the
  726. * btree root is stored in the inode.
  727. */
  728. if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
  729. (lev == cur->bc_nlevels - 1))
  730. return 0;
  731. if ((cur->bc_ra[lev] | lr) == cur->bc_ra[lev])
  732. return 0;
  733. cur->bc_ra[lev] |= lr;
  734. block = XFS_BUF_TO_BLOCK(cur->bc_bufs[lev]);
  735. if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
  736. return xfs_btree_readahead_lblock(cur, lr, block);
  737. return xfs_btree_readahead_sblock(cur, lr, block);
  738. }
  739. /*
  740. * Set the buffer for level "lev" in the cursor to bp, releasing
  741. * any previous buffer.
  742. */
  743. void
  744. xfs_btree_setbuf(
  745. xfs_btree_cur_t *cur, /* btree cursor */
  746. int lev, /* level in btree */
  747. xfs_buf_t *bp) /* new buffer to set */
  748. {
  749. xfs_btree_block_t *b; /* btree block */
  750. xfs_buf_t *obp; /* old buffer pointer */
  751. obp = cur->bc_bufs[lev];
  752. if (obp)
  753. xfs_trans_brelse(cur->bc_tp, obp);
  754. cur->bc_bufs[lev] = bp;
  755. cur->bc_ra[lev] = 0;
  756. if (!bp)
  757. return;
  758. b = XFS_BUF_TO_BLOCK(bp);
  759. if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
  760. if (be64_to_cpu(b->bb_u.l.bb_leftsib) == NULLDFSBNO)
  761. cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA;
  762. if (be64_to_cpu(b->bb_u.l.bb_rightsib) == NULLDFSBNO)
  763. cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA;
  764. } else {
  765. if (be32_to_cpu(b->bb_u.s.bb_leftsib) == NULLAGBLOCK)
  766. cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA;
  767. if (be32_to_cpu(b->bb_u.s.bb_rightsib) == NULLAGBLOCK)
  768. cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA;
  769. }
  770. }