xfs_btree.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914
  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_h.bb_level), cur);
  63. case XFS_BTNUM_BMAP:
  64. return (int)XFS_BMAP_BLOCK_IMAXRECS(
  65. be16_to_cpu(block->bb_h.bb_level), cur);
  66. case XFS_BTNUM_INO:
  67. return (int)XFS_INOBT_BLOCK_MAXRECS(
  68. be16_to_cpu(block->bb_h.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 (XFS_BTREE_LONG_PTRS(cur->bc_btnum))
  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 = xfs_btree_init_cursor(mp, tp, cur->bc_private.a.agbp,
  367. cur->bc_private.a.agno, cur->bc_btnum, cur->bc_private.b.ip,
  368. cur->bc_private.b.whichfork);
  369. /*
  370. * Copy the record currently in the cursor.
  371. */
  372. new->bc_rec = cur->bc_rec;
  373. /*
  374. * For each level current, re-get the buffer and copy the ptr value.
  375. */
  376. for (i = 0; i < new->bc_nlevels; i++) {
  377. new->bc_ptrs[i] = cur->bc_ptrs[i];
  378. new->bc_ra[i] = cur->bc_ra[i];
  379. if ((bp = cur->bc_bufs[i])) {
  380. if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
  381. XFS_BUF_ADDR(bp), mp->m_bsize, 0, &bp))) {
  382. xfs_btree_del_cursor(new, error);
  383. *ncur = NULL;
  384. return error;
  385. }
  386. new->bc_bufs[i] = bp;
  387. ASSERT(bp);
  388. ASSERT(!XFS_BUF_GETERROR(bp));
  389. } else
  390. new->bc_bufs[i] = NULL;
  391. }
  392. /*
  393. * For bmap btrees, copy the firstblock, flist, and flags values,
  394. * since init cursor doesn't get them.
  395. */
  396. if (new->bc_btnum == XFS_BTNUM_BMAP) {
  397. new->bc_private.b.firstblock = cur->bc_private.b.firstblock;
  398. new->bc_private.b.flist = cur->bc_private.b.flist;
  399. new->bc_private.b.flags = cur->bc_private.b.flags;
  400. }
  401. *ncur = new;
  402. return 0;
  403. }
  404. /*
  405. * Retrieve the block pointer from the cursor at the given level.
  406. * This may be a bmap btree root or from a buffer.
  407. */
  408. STATIC xfs_btree_block_t * /* generic btree block pointer */
  409. xfs_btree_get_block(
  410. xfs_btree_cur_t *cur, /* btree cursor */
  411. int level, /* level in btree */
  412. xfs_buf_t **bpp) /* buffer containing the block */
  413. {
  414. xfs_btree_block_t *block; /* return value */
  415. xfs_buf_t *bp; /* return buffer */
  416. xfs_ifork_t *ifp; /* inode fork pointer */
  417. int whichfork; /* data or attr fork */
  418. if (cur->bc_btnum == XFS_BTNUM_BMAP && level == cur->bc_nlevels - 1) {
  419. whichfork = cur->bc_private.b.whichfork;
  420. ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, whichfork);
  421. block = (xfs_btree_block_t *)ifp->if_broot;
  422. bp = NULL;
  423. } else {
  424. bp = cur->bc_bufs[level];
  425. block = XFS_BUF_TO_BLOCK(bp);
  426. }
  427. ASSERT(block != NULL);
  428. *bpp = bp;
  429. return block;
  430. }
  431. /*
  432. * Get a buffer for the block, return it with no data read.
  433. * Long-form addressing.
  434. */
  435. xfs_buf_t * /* buffer for fsbno */
  436. xfs_btree_get_bufl(
  437. xfs_mount_t *mp, /* file system mount point */
  438. xfs_trans_t *tp, /* transaction pointer */
  439. xfs_fsblock_t fsbno, /* file system block number */
  440. uint lock) /* lock flags for get_buf */
  441. {
  442. xfs_buf_t *bp; /* buffer pointer (return value) */
  443. xfs_daddr_t d; /* real disk block address */
  444. ASSERT(fsbno != NULLFSBLOCK);
  445. d = XFS_FSB_TO_DADDR(mp, fsbno);
  446. bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock);
  447. ASSERT(bp);
  448. ASSERT(!XFS_BUF_GETERROR(bp));
  449. return bp;
  450. }
  451. /*
  452. * Get a buffer for the block, return it with no data read.
  453. * Short-form addressing.
  454. */
  455. xfs_buf_t * /* buffer for agno/agbno */
  456. xfs_btree_get_bufs(
  457. xfs_mount_t *mp, /* file system mount point */
  458. xfs_trans_t *tp, /* transaction pointer */
  459. xfs_agnumber_t agno, /* allocation group number */
  460. xfs_agblock_t agbno, /* allocation group block number */
  461. uint lock) /* lock flags for get_buf */
  462. {
  463. xfs_buf_t *bp; /* buffer pointer (return value) */
  464. xfs_daddr_t d; /* real disk block address */
  465. ASSERT(agno != NULLAGNUMBER);
  466. ASSERT(agbno != NULLAGBLOCK);
  467. d = XFS_AGB_TO_DADDR(mp, agno, agbno);
  468. bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock);
  469. ASSERT(bp);
  470. ASSERT(!XFS_BUF_GETERROR(bp));
  471. return bp;
  472. }
  473. /*
  474. * Allocate a new btree cursor.
  475. * The cursor is either for allocation (A) or bmap (B) or inodes (I).
  476. */
  477. xfs_btree_cur_t * /* new btree cursor */
  478. xfs_btree_init_cursor(
  479. xfs_mount_t *mp, /* file system mount point */
  480. xfs_trans_t *tp, /* transaction pointer */
  481. xfs_buf_t *agbp, /* (A only) buffer for agf structure */
  482. /* (I only) buffer for agi structure */
  483. xfs_agnumber_t agno, /* (AI only) allocation group number */
  484. xfs_btnum_t btnum, /* btree identifier */
  485. xfs_inode_t *ip, /* (B only) inode owning the btree */
  486. int whichfork) /* (B only) data or attr fork */
  487. {
  488. xfs_agf_t *agf; /* (A) allocation group freespace */
  489. xfs_agi_t *agi; /* (I) allocation group inodespace */
  490. xfs_btree_cur_t *cur; /* return value */
  491. xfs_ifork_t *ifp; /* (I) inode fork pointer */
  492. int nlevels=0; /* number of levels in the btree */
  493. ASSERT(xfs_btree_cur_zone != NULL);
  494. /*
  495. * Allocate a new cursor.
  496. */
  497. cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP);
  498. /*
  499. * Deduce the number of btree levels from the arguments.
  500. */
  501. switch (btnum) {
  502. case XFS_BTNUM_BNO:
  503. case XFS_BTNUM_CNT:
  504. agf = XFS_BUF_TO_AGF(agbp);
  505. nlevels = be32_to_cpu(agf->agf_levels[btnum]);
  506. break;
  507. case XFS_BTNUM_BMAP:
  508. ifp = XFS_IFORK_PTR(ip, whichfork);
  509. nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1;
  510. break;
  511. case XFS_BTNUM_INO:
  512. agi = XFS_BUF_TO_AGI(agbp);
  513. nlevels = be32_to_cpu(agi->agi_level);
  514. break;
  515. default:
  516. ASSERT(0);
  517. }
  518. /*
  519. * Fill in the common fields.
  520. */
  521. cur->bc_tp = tp;
  522. cur->bc_mp = mp;
  523. cur->bc_nlevels = nlevels;
  524. cur->bc_btnum = btnum;
  525. cur->bc_blocklog = mp->m_sb.sb_blocklog;
  526. /*
  527. * Fill in private fields.
  528. */
  529. switch (btnum) {
  530. case XFS_BTNUM_BNO:
  531. case XFS_BTNUM_CNT:
  532. /*
  533. * Allocation btree fields.
  534. */
  535. cur->bc_private.a.agbp = agbp;
  536. cur->bc_private.a.agno = agno;
  537. break;
  538. case XFS_BTNUM_INO:
  539. /*
  540. * Inode allocation btree fields.
  541. */
  542. cur->bc_private.a.agbp = agbp;
  543. cur->bc_private.a.agno = agno;
  544. break;
  545. case XFS_BTNUM_BMAP:
  546. /*
  547. * Bmap btree fields.
  548. */
  549. cur->bc_private.b.forksize = XFS_IFORK_SIZE(ip, whichfork);
  550. cur->bc_private.b.ip = ip;
  551. cur->bc_private.b.firstblock = NULLFSBLOCK;
  552. cur->bc_private.b.flist = NULL;
  553. cur->bc_private.b.allocated = 0;
  554. cur->bc_private.b.flags = 0;
  555. cur->bc_private.b.whichfork = whichfork;
  556. break;
  557. default:
  558. ASSERT(0);
  559. }
  560. return cur;
  561. }
  562. /*
  563. * Check for the cursor referring to the last block at the given level.
  564. */
  565. int /* 1=is last block, 0=not last block */
  566. xfs_btree_islastblock(
  567. xfs_btree_cur_t *cur, /* btree cursor */
  568. int level) /* level to check */
  569. {
  570. xfs_btree_block_t *block; /* generic btree block pointer */
  571. xfs_buf_t *bp; /* buffer containing block */
  572. block = xfs_btree_get_block(cur, level, &bp);
  573. xfs_btree_check_block(cur, block, level, bp);
  574. if (XFS_BTREE_LONG_PTRS(cur->bc_btnum))
  575. return be64_to_cpu(block->bb_u.l.bb_rightsib) == NULLDFSBNO;
  576. else
  577. return be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK;
  578. }
  579. /*
  580. * Change the cursor to point to the first record at the given level.
  581. * Other levels are unaffected.
  582. */
  583. int /* success=1, failure=0 */
  584. xfs_btree_firstrec(
  585. xfs_btree_cur_t *cur, /* btree cursor */
  586. int level) /* level to change */
  587. {
  588. xfs_btree_block_t *block; /* generic btree block pointer */
  589. xfs_buf_t *bp; /* buffer containing block */
  590. /*
  591. * Get the block pointer for this level.
  592. */
  593. block = xfs_btree_get_block(cur, level, &bp);
  594. xfs_btree_check_block(cur, block, level, bp);
  595. /*
  596. * It's empty, there is no such record.
  597. */
  598. if (!block->bb_h.bb_numrecs)
  599. return 0;
  600. /*
  601. * Set the ptr value to 1, that's the first record/key.
  602. */
  603. cur->bc_ptrs[level] = 1;
  604. return 1;
  605. }
  606. /*
  607. * Change the cursor to point to the last record in the current block
  608. * at the given level. Other levels are unaffected.
  609. */
  610. int /* success=1, failure=0 */
  611. xfs_btree_lastrec(
  612. xfs_btree_cur_t *cur, /* btree cursor */
  613. int level) /* level to change */
  614. {
  615. xfs_btree_block_t *block; /* generic btree block pointer */
  616. xfs_buf_t *bp; /* buffer containing block */
  617. /*
  618. * Get the block pointer for this level.
  619. */
  620. block = xfs_btree_get_block(cur, level, &bp);
  621. xfs_btree_check_block(cur, block, level, bp);
  622. /*
  623. * It's empty, there is no such record.
  624. */
  625. if (!block->bb_h.bb_numrecs)
  626. return 0;
  627. /*
  628. * Set the ptr value to numrecs, that's the last record/key.
  629. */
  630. cur->bc_ptrs[level] = be16_to_cpu(block->bb_h.bb_numrecs);
  631. return 1;
  632. }
  633. /*
  634. * Compute first and last byte offsets for the fields given.
  635. * Interprets the offsets table, which contains struct field offsets.
  636. */
  637. void
  638. xfs_btree_offsets(
  639. __int64_t fields, /* bitmask of fields */
  640. const short *offsets, /* table of field offsets */
  641. int nbits, /* number of bits to inspect */
  642. int *first, /* output: first byte offset */
  643. int *last) /* output: last byte offset */
  644. {
  645. int i; /* current bit number */
  646. __int64_t imask; /* mask for current bit number */
  647. ASSERT(fields != 0);
  648. /*
  649. * Find the lowest bit, so the first byte offset.
  650. */
  651. for (i = 0, imask = 1LL; ; i++, imask <<= 1) {
  652. if (imask & fields) {
  653. *first = offsets[i];
  654. break;
  655. }
  656. }
  657. /*
  658. * Find the highest bit, so the last byte offset.
  659. */
  660. for (i = nbits - 1, imask = 1LL << i; ; i--, imask >>= 1) {
  661. if (imask & fields) {
  662. *last = offsets[i + 1] - 1;
  663. break;
  664. }
  665. }
  666. }
  667. /*
  668. * Get a buffer for the block, return it read in.
  669. * Long-form addressing.
  670. */
  671. int /* error */
  672. xfs_btree_read_bufl(
  673. xfs_mount_t *mp, /* file system mount point */
  674. xfs_trans_t *tp, /* transaction pointer */
  675. xfs_fsblock_t fsbno, /* file system block number */
  676. uint lock, /* lock flags for read_buf */
  677. xfs_buf_t **bpp, /* buffer for fsbno */
  678. int refval) /* ref count value for buffer */
  679. {
  680. xfs_buf_t *bp; /* return value */
  681. xfs_daddr_t d; /* real disk block address */
  682. int error;
  683. ASSERT(fsbno != NULLFSBLOCK);
  684. d = XFS_FSB_TO_DADDR(mp, fsbno);
  685. if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
  686. mp->m_bsize, lock, &bp))) {
  687. return error;
  688. }
  689. ASSERT(!bp || !XFS_BUF_GETERROR(bp));
  690. if (bp != NULL) {
  691. XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval);
  692. }
  693. *bpp = bp;
  694. return 0;
  695. }
  696. /*
  697. * Get a buffer for the block, return it read in.
  698. * Short-form addressing.
  699. */
  700. int /* error */
  701. xfs_btree_read_bufs(
  702. xfs_mount_t *mp, /* file system mount point */
  703. xfs_trans_t *tp, /* transaction pointer */
  704. xfs_agnumber_t agno, /* allocation group number */
  705. xfs_agblock_t agbno, /* allocation group block number */
  706. uint lock, /* lock flags for read_buf */
  707. xfs_buf_t **bpp, /* buffer for agno/agbno */
  708. int refval) /* ref count value for buffer */
  709. {
  710. xfs_buf_t *bp; /* return value */
  711. xfs_daddr_t d; /* real disk block address */
  712. int error;
  713. ASSERT(agno != NULLAGNUMBER);
  714. ASSERT(agbno != NULLAGBLOCK);
  715. d = XFS_AGB_TO_DADDR(mp, agno, agbno);
  716. if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
  717. mp->m_bsize, lock, &bp))) {
  718. return error;
  719. }
  720. ASSERT(!bp || !XFS_BUF_GETERROR(bp));
  721. if (bp != NULL) {
  722. switch (refval) {
  723. case XFS_ALLOC_BTREE_REF:
  724. XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval);
  725. break;
  726. case XFS_INO_BTREE_REF:
  727. XFS_BUF_SET_VTYPE_REF(bp, B_FS_INOMAP, refval);
  728. break;
  729. }
  730. }
  731. *bpp = bp;
  732. return 0;
  733. }
  734. /*
  735. * Read-ahead the block, don't wait for it, don't return a buffer.
  736. * Long-form addressing.
  737. */
  738. /* ARGSUSED */
  739. void
  740. xfs_btree_reada_bufl(
  741. xfs_mount_t *mp, /* file system mount point */
  742. xfs_fsblock_t fsbno, /* file system block number */
  743. xfs_extlen_t count) /* count of filesystem blocks */
  744. {
  745. xfs_daddr_t d;
  746. ASSERT(fsbno != NULLFSBLOCK);
  747. d = XFS_FSB_TO_DADDR(mp, fsbno);
  748. xfs_baread(mp->m_ddev_targp, d, mp->m_bsize * count);
  749. }
  750. /*
  751. * Read-ahead the block, don't wait for it, don't return a buffer.
  752. * Short-form addressing.
  753. */
  754. /* ARGSUSED */
  755. void
  756. xfs_btree_reada_bufs(
  757. xfs_mount_t *mp, /* file system mount point */
  758. xfs_agnumber_t agno, /* allocation group number */
  759. xfs_agblock_t agbno, /* allocation group block number */
  760. xfs_extlen_t count) /* count of filesystem blocks */
  761. {
  762. xfs_daddr_t d;
  763. ASSERT(agno != NULLAGNUMBER);
  764. ASSERT(agbno != NULLAGBLOCK);
  765. d = XFS_AGB_TO_DADDR(mp, agno, agbno);
  766. xfs_baread(mp->m_ddev_targp, d, mp->m_bsize * count);
  767. }
  768. /*
  769. * Read-ahead btree blocks, at the given level.
  770. * Bits in lr are set from XFS_BTCUR_{LEFT,RIGHT}RA.
  771. */
  772. int
  773. xfs_btree_readahead_core(
  774. xfs_btree_cur_t *cur, /* btree cursor */
  775. int lev, /* level in btree */
  776. int lr) /* left/right bits */
  777. {
  778. xfs_alloc_block_t *a;
  779. xfs_bmbt_block_t *b;
  780. xfs_inobt_block_t *i;
  781. int rval = 0;
  782. ASSERT(cur->bc_bufs[lev] != NULL);
  783. cur->bc_ra[lev] |= lr;
  784. switch (cur->bc_btnum) {
  785. case XFS_BTNUM_BNO:
  786. case XFS_BTNUM_CNT:
  787. a = XFS_BUF_TO_ALLOC_BLOCK(cur->bc_bufs[lev]);
  788. if ((lr & XFS_BTCUR_LEFTRA) && be32_to_cpu(a->bb_leftsib) != NULLAGBLOCK) {
  789. xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno,
  790. be32_to_cpu(a->bb_leftsib), 1);
  791. rval++;
  792. }
  793. if ((lr & XFS_BTCUR_RIGHTRA) && be32_to_cpu(a->bb_rightsib) != NULLAGBLOCK) {
  794. xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno,
  795. be32_to_cpu(a->bb_rightsib), 1);
  796. rval++;
  797. }
  798. break;
  799. case XFS_BTNUM_BMAP:
  800. b = XFS_BUF_TO_BMBT_BLOCK(cur->bc_bufs[lev]);
  801. if ((lr & XFS_BTCUR_LEFTRA) && be64_to_cpu(b->bb_leftsib) != NULLDFSBNO) {
  802. xfs_btree_reada_bufl(cur->bc_mp, be64_to_cpu(b->bb_leftsib), 1);
  803. rval++;
  804. }
  805. if ((lr & XFS_BTCUR_RIGHTRA) && be64_to_cpu(b->bb_rightsib) != NULLDFSBNO) {
  806. xfs_btree_reada_bufl(cur->bc_mp, be64_to_cpu(b->bb_rightsib), 1);
  807. rval++;
  808. }
  809. break;
  810. case XFS_BTNUM_INO:
  811. i = XFS_BUF_TO_INOBT_BLOCK(cur->bc_bufs[lev]);
  812. if ((lr & XFS_BTCUR_LEFTRA) && be32_to_cpu(i->bb_leftsib) != NULLAGBLOCK) {
  813. xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno,
  814. be32_to_cpu(i->bb_leftsib), 1);
  815. rval++;
  816. }
  817. if ((lr & XFS_BTCUR_RIGHTRA) && be32_to_cpu(i->bb_rightsib) != NULLAGBLOCK) {
  818. xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno,
  819. be32_to_cpu(i->bb_rightsib), 1);
  820. rval++;
  821. }
  822. break;
  823. default:
  824. ASSERT(0);
  825. }
  826. return rval;
  827. }
  828. /*
  829. * Set the buffer for level "lev" in the cursor to bp, releasing
  830. * any previous buffer.
  831. */
  832. void
  833. xfs_btree_setbuf(
  834. xfs_btree_cur_t *cur, /* btree cursor */
  835. int lev, /* level in btree */
  836. xfs_buf_t *bp) /* new buffer to set */
  837. {
  838. xfs_btree_block_t *b; /* btree block */
  839. xfs_buf_t *obp; /* old buffer pointer */
  840. obp = cur->bc_bufs[lev];
  841. if (obp)
  842. xfs_trans_brelse(cur->bc_tp, obp);
  843. cur->bc_bufs[lev] = bp;
  844. cur->bc_ra[lev] = 0;
  845. if (!bp)
  846. return;
  847. b = XFS_BUF_TO_BLOCK(bp);
  848. if (XFS_BTREE_LONG_PTRS(cur->bc_btnum)) {
  849. if (be64_to_cpu(b->bb_u.l.bb_leftsib) == NULLDFSBNO)
  850. cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA;
  851. if (be64_to_cpu(b->bb_u.l.bb_rightsib) == NULLDFSBNO)
  852. cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA;
  853. } else {
  854. if (be32_to_cpu(b->bb_u.s.bb_leftsib) == NULLAGBLOCK)
  855. cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA;
  856. if (be32_to_cpu(b->bb_u.s.bb_rightsib) == NULLAGBLOCK)
  857. cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA;
  858. }
  859. }