xfs_btree.c 26 KB

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