xfs_btree.c 25 KB

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