xfs_alloc_btree.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
  4. * All Rights Reserved.
  5. */
  6. #include "xfs.h"
  7. #include "xfs_fs.h"
  8. #include "xfs_shared.h"
  9. #include "xfs_format.h"
  10. #include "xfs_log_format.h"
  11. #include "xfs_trans_resv.h"
  12. #include "xfs_mount.h"
  13. #include "xfs_btree.h"
  14. #include "xfs_btree_staging.h"
  15. #include "xfs_alloc_btree.h"
  16. #include "xfs_alloc.h"
  17. #include "xfs_extent_busy.h"
  18. #include "xfs_error.h"
  19. #include "xfs_health.h"
  20. #include "xfs_trace.h"
  21. #include "xfs_trans.h"
  22. #include "xfs_ag.h"
  23. static struct kmem_cache *xfs_allocbt_cur_cache;
  24. STATIC struct xfs_btree_cur *
  25. xfs_bnobt_dup_cursor(
  26. struct xfs_btree_cur *cur)
  27. {
  28. return xfs_bnobt_init_cursor(cur->bc_mp, cur->bc_tp, cur->bc_ag.agbp,
  29. cur->bc_ag.pag);
  30. }
  31. STATIC struct xfs_btree_cur *
  32. xfs_cntbt_dup_cursor(
  33. struct xfs_btree_cur *cur)
  34. {
  35. return xfs_cntbt_init_cursor(cur->bc_mp, cur->bc_tp, cur->bc_ag.agbp,
  36. cur->bc_ag.pag);
  37. }
  38. STATIC void
  39. xfs_allocbt_set_root(
  40. struct xfs_btree_cur *cur,
  41. const union xfs_btree_ptr *ptr,
  42. int inc)
  43. {
  44. struct xfs_buf *agbp = cur->bc_ag.agbp;
  45. struct xfs_agf *agf = agbp->b_addr;
  46. ASSERT(ptr->s != 0);
  47. if (xfs_btree_is_bno(cur->bc_ops)) {
  48. agf->agf_bno_root = ptr->s;
  49. be32_add_cpu(&agf->agf_bno_level, inc);
  50. cur->bc_ag.pag->pagf_bno_level += inc;
  51. } else {
  52. agf->agf_cnt_root = ptr->s;
  53. be32_add_cpu(&agf->agf_cnt_level, inc);
  54. cur->bc_ag.pag->pagf_cnt_level += inc;
  55. }
  56. xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS);
  57. }
  58. STATIC int
  59. xfs_allocbt_alloc_block(
  60. struct xfs_btree_cur *cur,
  61. const union xfs_btree_ptr *start,
  62. union xfs_btree_ptr *new,
  63. int *stat)
  64. {
  65. int error;
  66. xfs_agblock_t bno;
  67. /* Allocate the new block from the freelist. If we can't, give up. */
  68. error = xfs_alloc_get_freelist(cur->bc_ag.pag, cur->bc_tp,
  69. cur->bc_ag.agbp, &bno, 1);
  70. if (error)
  71. return error;
  72. if (bno == NULLAGBLOCK) {
  73. *stat = 0;
  74. return 0;
  75. }
  76. atomic64_inc(&cur->bc_mp->m_allocbt_blks);
  77. xfs_extent_busy_reuse(cur->bc_mp, cur->bc_ag.pag, bno, 1, false);
  78. new->s = cpu_to_be32(bno);
  79. *stat = 1;
  80. return 0;
  81. }
  82. STATIC int
  83. xfs_allocbt_free_block(
  84. struct xfs_btree_cur *cur,
  85. struct xfs_buf *bp)
  86. {
  87. struct xfs_buf *agbp = cur->bc_ag.agbp;
  88. xfs_agblock_t bno;
  89. int error;
  90. bno = xfs_daddr_to_agbno(cur->bc_mp, xfs_buf_daddr(bp));
  91. error = xfs_alloc_put_freelist(cur->bc_ag.pag, cur->bc_tp, agbp, NULL,
  92. bno, 1);
  93. if (error)
  94. return error;
  95. atomic64_dec(&cur->bc_mp->m_allocbt_blks);
  96. xfs_extent_busy_insert(cur->bc_tp, agbp->b_pag, bno, 1,
  97. XFS_EXTENT_BUSY_SKIP_DISCARD);
  98. return 0;
  99. }
  100. STATIC int
  101. xfs_allocbt_get_minrecs(
  102. struct xfs_btree_cur *cur,
  103. int level)
  104. {
  105. return cur->bc_mp->m_alloc_mnr[level != 0];
  106. }
  107. STATIC int
  108. xfs_allocbt_get_maxrecs(
  109. struct xfs_btree_cur *cur,
  110. int level)
  111. {
  112. return cur->bc_mp->m_alloc_mxr[level != 0];
  113. }
  114. STATIC void
  115. xfs_allocbt_init_key_from_rec(
  116. union xfs_btree_key *key,
  117. const union xfs_btree_rec *rec)
  118. {
  119. key->alloc.ar_startblock = rec->alloc.ar_startblock;
  120. key->alloc.ar_blockcount = rec->alloc.ar_blockcount;
  121. }
  122. STATIC void
  123. xfs_bnobt_init_high_key_from_rec(
  124. union xfs_btree_key *key,
  125. const union xfs_btree_rec *rec)
  126. {
  127. __u32 x;
  128. x = be32_to_cpu(rec->alloc.ar_startblock);
  129. x += be32_to_cpu(rec->alloc.ar_blockcount) - 1;
  130. key->alloc.ar_startblock = cpu_to_be32(x);
  131. key->alloc.ar_blockcount = 0;
  132. }
  133. STATIC void
  134. xfs_cntbt_init_high_key_from_rec(
  135. union xfs_btree_key *key,
  136. const union xfs_btree_rec *rec)
  137. {
  138. key->alloc.ar_blockcount = rec->alloc.ar_blockcount;
  139. key->alloc.ar_startblock = 0;
  140. }
  141. STATIC void
  142. xfs_allocbt_init_rec_from_cur(
  143. struct xfs_btree_cur *cur,
  144. union xfs_btree_rec *rec)
  145. {
  146. rec->alloc.ar_startblock = cpu_to_be32(cur->bc_rec.a.ar_startblock);
  147. rec->alloc.ar_blockcount = cpu_to_be32(cur->bc_rec.a.ar_blockcount);
  148. }
  149. STATIC void
  150. xfs_allocbt_init_ptr_from_cur(
  151. struct xfs_btree_cur *cur,
  152. union xfs_btree_ptr *ptr)
  153. {
  154. struct xfs_agf *agf = cur->bc_ag.agbp->b_addr;
  155. ASSERT(cur->bc_ag.pag->pag_agno == be32_to_cpu(agf->agf_seqno));
  156. if (xfs_btree_is_bno(cur->bc_ops))
  157. ptr->s = agf->agf_bno_root;
  158. else
  159. ptr->s = agf->agf_cnt_root;
  160. }
  161. STATIC int64_t
  162. xfs_bnobt_key_diff(
  163. struct xfs_btree_cur *cur,
  164. const union xfs_btree_key *key)
  165. {
  166. struct xfs_alloc_rec_incore *rec = &cur->bc_rec.a;
  167. const struct xfs_alloc_rec *kp = &key->alloc;
  168. return (int64_t)be32_to_cpu(kp->ar_startblock) - rec->ar_startblock;
  169. }
  170. STATIC int64_t
  171. xfs_cntbt_key_diff(
  172. struct xfs_btree_cur *cur,
  173. const union xfs_btree_key *key)
  174. {
  175. struct xfs_alloc_rec_incore *rec = &cur->bc_rec.a;
  176. const struct xfs_alloc_rec *kp = &key->alloc;
  177. int64_t diff;
  178. diff = (int64_t)be32_to_cpu(kp->ar_blockcount) - rec->ar_blockcount;
  179. if (diff)
  180. return diff;
  181. return (int64_t)be32_to_cpu(kp->ar_startblock) - rec->ar_startblock;
  182. }
  183. STATIC int64_t
  184. xfs_bnobt_diff_two_keys(
  185. struct xfs_btree_cur *cur,
  186. const union xfs_btree_key *k1,
  187. const union xfs_btree_key *k2,
  188. const union xfs_btree_key *mask)
  189. {
  190. ASSERT(!mask || mask->alloc.ar_startblock);
  191. return (int64_t)be32_to_cpu(k1->alloc.ar_startblock) -
  192. be32_to_cpu(k2->alloc.ar_startblock);
  193. }
  194. STATIC int64_t
  195. xfs_cntbt_diff_two_keys(
  196. struct xfs_btree_cur *cur,
  197. const union xfs_btree_key *k1,
  198. const union xfs_btree_key *k2,
  199. const union xfs_btree_key *mask)
  200. {
  201. int64_t diff;
  202. ASSERT(!mask || (mask->alloc.ar_blockcount &&
  203. mask->alloc.ar_startblock));
  204. diff = be32_to_cpu(k1->alloc.ar_blockcount) -
  205. be32_to_cpu(k2->alloc.ar_blockcount);
  206. if (diff)
  207. return diff;
  208. return be32_to_cpu(k1->alloc.ar_startblock) -
  209. be32_to_cpu(k2->alloc.ar_startblock);
  210. }
  211. static xfs_failaddr_t
  212. xfs_allocbt_verify(
  213. struct xfs_buf *bp)
  214. {
  215. struct xfs_mount *mp = bp->b_mount;
  216. struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
  217. struct xfs_perag *pag = bp->b_pag;
  218. xfs_failaddr_t fa;
  219. unsigned int level;
  220. if (!xfs_verify_magic(bp, block->bb_magic))
  221. return __this_address;
  222. if (xfs_has_crc(mp)) {
  223. fa = xfs_btree_agblock_v5hdr_verify(bp);
  224. if (fa)
  225. return fa;
  226. }
  227. /*
  228. * The perag may not be attached during grow operations or fully
  229. * initialized from the AGF during log recovery. Therefore we can only
  230. * check against maximum tree depth from those contexts.
  231. *
  232. * Otherwise check against the per-tree limit. Peek at one of the
  233. * verifier magic values to determine the type of tree we're verifying
  234. * against.
  235. */
  236. level = be16_to_cpu(block->bb_level);
  237. if (pag && xfs_perag_initialised_agf(pag)) {
  238. unsigned int maxlevel, repair_maxlevel = 0;
  239. /*
  240. * Online repair could be rewriting the free space btrees, so
  241. * we'll validate against the larger of either tree while this
  242. * is going on.
  243. */
  244. if (bp->b_ops->magic[0] == cpu_to_be32(XFS_ABTC_MAGIC)) {
  245. maxlevel = pag->pagf_cnt_level;
  246. #ifdef CONFIG_XFS_ONLINE_REPAIR
  247. repair_maxlevel = pag->pagf_repair_cnt_level;
  248. #endif
  249. } else {
  250. maxlevel = pag->pagf_bno_level;
  251. #ifdef CONFIG_XFS_ONLINE_REPAIR
  252. repair_maxlevel = pag->pagf_repair_bno_level;
  253. #endif
  254. }
  255. if (level >= max(maxlevel, repair_maxlevel))
  256. return __this_address;
  257. } else if (level >= mp->m_alloc_maxlevels)
  258. return __this_address;
  259. return xfs_btree_agblock_verify(bp, mp->m_alloc_mxr[level != 0]);
  260. }
  261. static void
  262. xfs_allocbt_read_verify(
  263. struct xfs_buf *bp)
  264. {
  265. xfs_failaddr_t fa;
  266. if (!xfs_btree_agblock_verify_crc(bp))
  267. xfs_verifier_error(bp, -EFSBADCRC, __this_address);
  268. else {
  269. fa = xfs_allocbt_verify(bp);
  270. if (fa)
  271. xfs_verifier_error(bp, -EFSCORRUPTED, fa);
  272. }
  273. if (bp->b_error)
  274. trace_xfs_btree_corrupt(bp, _RET_IP_);
  275. }
  276. static void
  277. xfs_allocbt_write_verify(
  278. struct xfs_buf *bp)
  279. {
  280. xfs_failaddr_t fa;
  281. fa = xfs_allocbt_verify(bp);
  282. if (fa) {
  283. trace_xfs_btree_corrupt(bp, _RET_IP_);
  284. xfs_verifier_error(bp, -EFSCORRUPTED, fa);
  285. return;
  286. }
  287. xfs_btree_agblock_calc_crc(bp);
  288. }
  289. const struct xfs_buf_ops xfs_bnobt_buf_ops = {
  290. .name = "xfs_bnobt",
  291. .magic = { cpu_to_be32(XFS_ABTB_MAGIC),
  292. cpu_to_be32(XFS_ABTB_CRC_MAGIC) },
  293. .verify_read = xfs_allocbt_read_verify,
  294. .verify_write = xfs_allocbt_write_verify,
  295. .verify_struct = xfs_allocbt_verify,
  296. };
  297. const struct xfs_buf_ops xfs_cntbt_buf_ops = {
  298. .name = "xfs_cntbt",
  299. .magic = { cpu_to_be32(XFS_ABTC_MAGIC),
  300. cpu_to_be32(XFS_ABTC_CRC_MAGIC) },
  301. .verify_read = xfs_allocbt_read_verify,
  302. .verify_write = xfs_allocbt_write_verify,
  303. .verify_struct = xfs_allocbt_verify,
  304. };
  305. STATIC int
  306. xfs_bnobt_keys_inorder(
  307. struct xfs_btree_cur *cur,
  308. const union xfs_btree_key *k1,
  309. const union xfs_btree_key *k2)
  310. {
  311. return be32_to_cpu(k1->alloc.ar_startblock) <
  312. be32_to_cpu(k2->alloc.ar_startblock);
  313. }
  314. STATIC int
  315. xfs_bnobt_recs_inorder(
  316. struct xfs_btree_cur *cur,
  317. const union xfs_btree_rec *r1,
  318. const union xfs_btree_rec *r2)
  319. {
  320. return be32_to_cpu(r1->alloc.ar_startblock) +
  321. be32_to_cpu(r1->alloc.ar_blockcount) <=
  322. be32_to_cpu(r2->alloc.ar_startblock);
  323. }
  324. STATIC int
  325. xfs_cntbt_keys_inorder(
  326. struct xfs_btree_cur *cur,
  327. const union xfs_btree_key *k1,
  328. const union xfs_btree_key *k2)
  329. {
  330. return be32_to_cpu(k1->alloc.ar_blockcount) <
  331. be32_to_cpu(k2->alloc.ar_blockcount) ||
  332. (k1->alloc.ar_blockcount == k2->alloc.ar_blockcount &&
  333. be32_to_cpu(k1->alloc.ar_startblock) <
  334. be32_to_cpu(k2->alloc.ar_startblock));
  335. }
  336. STATIC int
  337. xfs_cntbt_recs_inorder(
  338. struct xfs_btree_cur *cur,
  339. const union xfs_btree_rec *r1,
  340. const union xfs_btree_rec *r2)
  341. {
  342. return be32_to_cpu(r1->alloc.ar_blockcount) <
  343. be32_to_cpu(r2->alloc.ar_blockcount) ||
  344. (r1->alloc.ar_blockcount == r2->alloc.ar_blockcount &&
  345. be32_to_cpu(r1->alloc.ar_startblock) <
  346. be32_to_cpu(r2->alloc.ar_startblock));
  347. }
  348. STATIC enum xbtree_key_contig
  349. xfs_allocbt_keys_contiguous(
  350. struct xfs_btree_cur *cur,
  351. const union xfs_btree_key *key1,
  352. const union xfs_btree_key *key2,
  353. const union xfs_btree_key *mask)
  354. {
  355. ASSERT(!mask || mask->alloc.ar_startblock);
  356. return xbtree_key_contig(be32_to_cpu(key1->alloc.ar_startblock),
  357. be32_to_cpu(key2->alloc.ar_startblock));
  358. }
  359. const struct xfs_btree_ops xfs_bnobt_ops = {
  360. .name = "bno",
  361. .type = XFS_BTREE_TYPE_AG,
  362. .rec_len = sizeof(xfs_alloc_rec_t),
  363. .key_len = sizeof(xfs_alloc_key_t),
  364. .ptr_len = XFS_BTREE_SHORT_PTR_LEN,
  365. .lru_refs = XFS_ALLOC_BTREE_REF,
  366. .statoff = XFS_STATS_CALC_INDEX(xs_abtb_2),
  367. .sick_mask = XFS_SICK_AG_BNOBT,
  368. .dup_cursor = xfs_bnobt_dup_cursor,
  369. .set_root = xfs_allocbt_set_root,
  370. .alloc_block = xfs_allocbt_alloc_block,
  371. .free_block = xfs_allocbt_free_block,
  372. .get_minrecs = xfs_allocbt_get_minrecs,
  373. .get_maxrecs = xfs_allocbt_get_maxrecs,
  374. .init_key_from_rec = xfs_allocbt_init_key_from_rec,
  375. .init_high_key_from_rec = xfs_bnobt_init_high_key_from_rec,
  376. .init_rec_from_cur = xfs_allocbt_init_rec_from_cur,
  377. .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur,
  378. .key_diff = xfs_bnobt_key_diff,
  379. .buf_ops = &xfs_bnobt_buf_ops,
  380. .diff_two_keys = xfs_bnobt_diff_two_keys,
  381. .keys_inorder = xfs_bnobt_keys_inorder,
  382. .recs_inorder = xfs_bnobt_recs_inorder,
  383. .keys_contiguous = xfs_allocbt_keys_contiguous,
  384. };
  385. const struct xfs_btree_ops xfs_cntbt_ops = {
  386. .name = "cnt",
  387. .type = XFS_BTREE_TYPE_AG,
  388. .rec_len = sizeof(xfs_alloc_rec_t),
  389. .key_len = sizeof(xfs_alloc_key_t),
  390. .ptr_len = XFS_BTREE_SHORT_PTR_LEN,
  391. .lru_refs = XFS_ALLOC_BTREE_REF,
  392. .statoff = XFS_STATS_CALC_INDEX(xs_abtc_2),
  393. .sick_mask = XFS_SICK_AG_CNTBT,
  394. .dup_cursor = xfs_cntbt_dup_cursor,
  395. .set_root = xfs_allocbt_set_root,
  396. .alloc_block = xfs_allocbt_alloc_block,
  397. .free_block = xfs_allocbt_free_block,
  398. .get_minrecs = xfs_allocbt_get_minrecs,
  399. .get_maxrecs = xfs_allocbt_get_maxrecs,
  400. .init_key_from_rec = xfs_allocbt_init_key_from_rec,
  401. .init_high_key_from_rec = xfs_cntbt_init_high_key_from_rec,
  402. .init_rec_from_cur = xfs_allocbt_init_rec_from_cur,
  403. .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur,
  404. .key_diff = xfs_cntbt_key_diff,
  405. .buf_ops = &xfs_cntbt_buf_ops,
  406. .diff_two_keys = xfs_cntbt_diff_two_keys,
  407. .keys_inorder = xfs_cntbt_keys_inorder,
  408. .recs_inorder = xfs_cntbt_recs_inorder,
  409. .keys_contiguous = NULL, /* not needed right now */
  410. };
  411. /*
  412. * Allocate a new bnobt cursor.
  413. *
  414. * For staging cursors tp and agbp are NULL.
  415. */
  416. struct xfs_btree_cur *
  417. xfs_bnobt_init_cursor(
  418. struct xfs_mount *mp,
  419. struct xfs_trans *tp,
  420. struct xfs_buf *agbp,
  421. struct xfs_perag *pag)
  422. {
  423. struct xfs_btree_cur *cur;
  424. cur = xfs_btree_alloc_cursor(mp, tp, &xfs_bnobt_ops,
  425. mp->m_alloc_maxlevels, xfs_allocbt_cur_cache);
  426. cur->bc_ag.pag = xfs_perag_hold(pag);
  427. cur->bc_ag.agbp = agbp;
  428. if (agbp) {
  429. struct xfs_agf *agf = agbp->b_addr;
  430. cur->bc_nlevels = be32_to_cpu(agf->agf_bno_level);
  431. }
  432. return cur;
  433. }
  434. /*
  435. * Allocate a new cntbt cursor.
  436. *
  437. * For staging cursors tp and agbp are NULL.
  438. */
  439. struct xfs_btree_cur *
  440. xfs_cntbt_init_cursor(
  441. struct xfs_mount *mp,
  442. struct xfs_trans *tp,
  443. struct xfs_buf *agbp,
  444. struct xfs_perag *pag)
  445. {
  446. struct xfs_btree_cur *cur;
  447. cur = xfs_btree_alloc_cursor(mp, tp, &xfs_cntbt_ops,
  448. mp->m_alloc_maxlevels, xfs_allocbt_cur_cache);
  449. cur->bc_ag.pag = xfs_perag_hold(pag);
  450. cur->bc_ag.agbp = agbp;
  451. if (agbp) {
  452. struct xfs_agf *agf = agbp->b_addr;
  453. cur->bc_nlevels = be32_to_cpu(agf->agf_cnt_level);
  454. }
  455. return cur;
  456. }
  457. /*
  458. * Install a new free space btree root. Caller is responsible for invalidating
  459. * and freeing the old btree blocks.
  460. */
  461. void
  462. xfs_allocbt_commit_staged_btree(
  463. struct xfs_btree_cur *cur,
  464. struct xfs_trans *tp,
  465. struct xfs_buf *agbp)
  466. {
  467. struct xfs_agf *agf = agbp->b_addr;
  468. struct xbtree_afakeroot *afake = cur->bc_ag.afake;
  469. ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
  470. if (xfs_btree_is_bno(cur->bc_ops)) {
  471. agf->agf_bno_root = cpu_to_be32(afake->af_root);
  472. agf->agf_bno_level = cpu_to_be32(afake->af_levels);
  473. } else {
  474. agf->agf_cnt_root = cpu_to_be32(afake->af_root);
  475. agf->agf_cnt_level = cpu_to_be32(afake->af_levels);
  476. }
  477. xfs_alloc_log_agf(tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS);
  478. xfs_btree_commit_afakeroot(cur, tp, agbp);
  479. }
  480. /* Calculate number of records in an alloc btree block. */
  481. static inline unsigned int
  482. xfs_allocbt_block_maxrecs(
  483. unsigned int blocklen,
  484. bool leaf)
  485. {
  486. if (leaf)
  487. return blocklen / sizeof(xfs_alloc_rec_t);
  488. return blocklen / (sizeof(xfs_alloc_key_t) + sizeof(xfs_alloc_ptr_t));
  489. }
  490. /*
  491. * Calculate number of records in an alloc btree block.
  492. */
  493. unsigned int
  494. xfs_allocbt_maxrecs(
  495. struct xfs_mount *mp,
  496. unsigned int blocklen,
  497. bool leaf)
  498. {
  499. blocklen -= XFS_ALLOC_BLOCK_LEN(mp);
  500. return xfs_allocbt_block_maxrecs(blocklen, leaf);
  501. }
  502. /* Free space btrees are at their largest when every other block is free. */
  503. #define XFS_MAX_FREESP_RECORDS ((XFS_MAX_AG_BLOCKS + 1) / 2)
  504. /* Compute the max possible height for free space btrees. */
  505. unsigned int
  506. xfs_allocbt_maxlevels_ondisk(void)
  507. {
  508. unsigned int minrecs[2];
  509. unsigned int blocklen;
  510. blocklen = min(XFS_MIN_BLOCKSIZE - XFS_BTREE_SBLOCK_LEN,
  511. XFS_MIN_CRC_BLOCKSIZE - XFS_BTREE_SBLOCK_CRC_LEN);
  512. minrecs[0] = xfs_allocbt_block_maxrecs(blocklen, true) / 2;
  513. minrecs[1] = xfs_allocbt_block_maxrecs(blocklen, false) / 2;
  514. return xfs_btree_compute_maxlevels(minrecs, XFS_MAX_FREESP_RECORDS);
  515. }
  516. /* Calculate the freespace btree size for some records. */
  517. xfs_extlen_t
  518. xfs_allocbt_calc_size(
  519. struct xfs_mount *mp,
  520. unsigned long long len)
  521. {
  522. return xfs_btree_calc_size(mp->m_alloc_mnr, len);
  523. }
  524. int __init
  525. xfs_allocbt_init_cur_cache(void)
  526. {
  527. xfs_allocbt_cur_cache = kmem_cache_create("xfs_bnobt_cur",
  528. xfs_btree_cur_sizeof(xfs_allocbt_maxlevels_ondisk()),
  529. 0, 0, NULL);
  530. if (!xfs_allocbt_cur_cache)
  531. return -ENOMEM;
  532. return 0;
  533. }
  534. void
  535. xfs_allocbt_destroy_cur_cache(void)
  536. {
  537. kmem_cache_destroy(xfs_allocbt_cur_cache);
  538. xfs_allocbt_cur_cache = NULL;
  539. }