xfs_ialloc_btree.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837
  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_bit.h"
  13. #include "xfs_mount.h"
  14. #include "xfs_btree.h"
  15. #include "xfs_btree_staging.h"
  16. #include "xfs_ialloc.h"
  17. #include "xfs_ialloc_btree.h"
  18. #include "xfs_alloc.h"
  19. #include "xfs_error.h"
  20. #include "xfs_health.h"
  21. #include "xfs_trace.h"
  22. #include "xfs_trans.h"
  23. #include "xfs_rmap.h"
  24. #include "xfs_ag.h"
  25. static struct kmem_cache *xfs_inobt_cur_cache;
  26. STATIC int
  27. xfs_inobt_get_minrecs(
  28. struct xfs_btree_cur *cur,
  29. int level)
  30. {
  31. return M_IGEO(cur->bc_mp)->inobt_mnr[level != 0];
  32. }
  33. STATIC struct xfs_btree_cur *
  34. xfs_inobt_dup_cursor(
  35. struct xfs_btree_cur *cur)
  36. {
  37. return xfs_inobt_init_cursor(cur->bc_ag.pag, cur->bc_tp,
  38. cur->bc_ag.agbp);
  39. }
  40. STATIC struct xfs_btree_cur *
  41. xfs_finobt_dup_cursor(
  42. struct xfs_btree_cur *cur)
  43. {
  44. return xfs_finobt_init_cursor(cur->bc_ag.pag, cur->bc_tp,
  45. cur->bc_ag.agbp);
  46. }
  47. STATIC void
  48. xfs_inobt_set_root(
  49. struct xfs_btree_cur *cur,
  50. const union xfs_btree_ptr *nptr,
  51. int inc) /* level change */
  52. {
  53. struct xfs_buf *agbp = cur->bc_ag.agbp;
  54. struct xfs_agi *agi = agbp->b_addr;
  55. agi->agi_root = nptr->s;
  56. be32_add_cpu(&agi->agi_level, inc);
  57. xfs_ialloc_log_agi(cur->bc_tp, agbp, XFS_AGI_ROOT | XFS_AGI_LEVEL);
  58. }
  59. STATIC void
  60. xfs_finobt_set_root(
  61. struct xfs_btree_cur *cur,
  62. const union xfs_btree_ptr *nptr,
  63. int inc) /* level change */
  64. {
  65. struct xfs_buf *agbp = cur->bc_ag.agbp;
  66. struct xfs_agi *agi = agbp->b_addr;
  67. agi->agi_free_root = nptr->s;
  68. be32_add_cpu(&agi->agi_free_level, inc);
  69. xfs_ialloc_log_agi(cur->bc_tp, agbp,
  70. XFS_AGI_FREE_ROOT | XFS_AGI_FREE_LEVEL);
  71. }
  72. /* Update the inode btree block counter for this btree. */
  73. static inline void
  74. xfs_inobt_mod_blockcount(
  75. struct xfs_btree_cur *cur,
  76. int howmuch)
  77. {
  78. struct xfs_buf *agbp = cur->bc_ag.agbp;
  79. struct xfs_agi *agi = agbp->b_addr;
  80. if (!xfs_has_inobtcounts(cur->bc_mp))
  81. return;
  82. if (xfs_btree_is_fino(cur->bc_ops))
  83. be32_add_cpu(&agi->agi_fblocks, howmuch);
  84. else
  85. be32_add_cpu(&agi->agi_iblocks, howmuch);
  86. xfs_ialloc_log_agi(cur->bc_tp, agbp, XFS_AGI_IBLOCKS);
  87. }
  88. STATIC int
  89. __xfs_inobt_alloc_block(
  90. struct xfs_btree_cur *cur,
  91. const union xfs_btree_ptr *start,
  92. union xfs_btree_ptr *new,
  93. int *stat,
  94. enum xfs_ag_resv_type resv)
  95. {
  96. xfs_alloc_arg_t args; /* block allocation args */
  97. int error; /* error return value */
  98. xfs_agblock_t sbno = be32_to_cpu(start->s);
  99. memset(&args, 0, sizeof(args));
  100. args.tp = cur->bc_tp;
  101. args.mp = cur->bc_mp;
  102. args.pag = cur->bc_ag.pag;
  103. args.oinfo = XFS_RMAP_OINFO_INOBT;
  104. args.minlen = 1;
  105. args.maxlen = 1;
  106. args.prod = 1;
  107. args.resv = resv;
  108. error = xfs_alloc_vextent_near_bno(&args,
  109. XFS_AGB_TO_FSB(args.mp, args.pag->pag_agno, sbno));
  110. if (error)
  111. return error;
  112. if (args.fsbno == NULLFSBLOCK) {
  113. *stat = 0;
  114. return 0;
  115. }
  116. ASSERT(args.len == 1);
  117. new->s = cpu_to_be32(XFS_FSB_TO_AGBNO(args.mp, args.fsbno));
  118. *stat = 1;
  119. xfs_inobt_mod_blockcount(cur, 1);
  120. return 0;
  121. }
  122. STATIC int
  123. xfs_inobt_alloc_block(
  124. struct xfs_btree_cur *cur,
  125. const union xfs_btree_ptr *start,
  126. union xfs_btree_ptr *new,
  127. int *stat)
  128. {
  129. return __xfs_inobt_alloc_block(cur, start, new, stat, XFS_AG_RESV_NONE);
  130. }
  131. STATIC int
  132. xfs_finobt_alloc_block(
  133. struct xfs_btree_cur *cur,
  134. const union xfs_btree_ptr *start,
  135. union xfs_btree_ptr *new,
  136. int *stat)
  137. {
  138. if (cur->bc_mp->m_finobt_nores)
  139. return xfs_inobt_alloc_block(cur, start, new, stat);
  140. return __xfs_inobt_alloc_block(cur, start, new, stat,
  141. XFS_AG_RESV_METADATA);
  142. }
  143. STATIC int
  144. __xfs_inobt_free_block(
  145. struct xfs_btree_cur *cur,
  146. struct xfs_buf *bp,
  147. enum xfs_ag_resv_type resv)
  148. {
  149. xfs_fsblock_t fsbno;
  150. xfs_inobt_mod_blockcount(cur, -1);
  151. fsbno = XFS_DADDR_TO_FSB(cur->bc_mp, xfs_buf_daddr(bp));
  152. return xfs_free_extent_later(cur->bc_tp, fsbno, 1,
  153. &XFS_RMAP_OINFO_INOBT, resv, 0);
  154. }
  155. STATIC int
  156. xfs_inobt_free_block(
  157. struct xfs_btree_cur *cur,
  158. struct xfs_buf *bp)
  159. {
  160. return __xfs_inobt_free_block(cur, bp, XFS_AG_RESV_NONE);
  161. }
  162. STATIC int
  163. xfs_finobt_free_block(
  164. struct xfs_btree_cur *cur,
  165. struct xfs_buf *bp)
  166. {
  167. if (cur->bc_mp->m_finobt_nores)
  168. return xfs_inobt_free_block(cur, bp);
  169. return __xfs_inobt_free_block(cur, bp, XFS_AG_RESV_METADATA);
  170. }
  171. STATIC int
  172. xfs_inobt_get_maxrecs(
  173. struct xfs_btree_cur *cur,
  174. int level)
  175. {
  176. return M_IGEO(cur->bc_mp)->inobt_mxr[level != 0];
  177. }
  178. STATIC void
  179. xfs_inobt_init_key_from_rec(
  180. union xfs_btree_key *key,
  181. const union xfs_btree_rec *rec)
  182. {
  183. key->inobt.ir_startino = rec->inobt.ir_startino;
  184. }
  185. STATIC void
  186. xfs_inobt_init_high_key_from_rec(
  187. union xfs_btree_key *key,
  188. const union xfs_btree_rec *rec)
  189. {
  190. __u32 x;
  191. x = be32_to_cpu(rec->inobt.ir_startino);
  192. x += XFS_INODES_PER_CHUNK - 1;
  193. key->inobt.ir_startino = cpu_to_be32(x);
  194. }
  195. STATIC void
  196. xfs_inobt_init_rec_from_cur(
  197. struct xfs_btree_cur *cur,
  198. union xfs_btree_rec *rec)
  199. {
  200. rec->inobt.ir_startino = cpu_to_be32(cur->bc_rec.i.ir_startino);
  201. if (xfs_has_sparseinodes(cur->bc_mp)) {
  202. rec->inobt.ir_u.sp.ir_holemask =
  203. cpu_to_be16(cur->bc_rec.i.ir_holemask);
  204. rec->inobt.ir_u.sp.ir_count = cur->bc_rec.i.ir_count;
  205. rec->inobt.ir_u.sp.ir_freecount = cur->bc_rec.i.ir_freecount;
  206. } else {
  207. /* ir_holemask/ir_count not supported on-disk */
  208. rec->inobt.ir_u.f.ir_freecount =
  209. cpu_to_be32(cur->bc_rec.i.ir_freecount);
  210. }
  211. rec->inobt.ir_free = cpu_to_be64(cur->bc_rec.i.ir_free);
  212. }
  213. /*
  214. * initial value of ptr for lookup
  215. */
  216. STATIC void
  217. xfs_inobt_init_ptr_from_cur(
  218. struct xfs_btree_cur *cur,
  219. union xfs_btree_ptr *ptr)
  220. {
  221. struct xfs_agi *agi = cur->bc_ag.agbp->b_addr;
  222. ASSERT(cur->bc_ag.pag->pag_agno == be32_to_cpu(agi->agi_seqno));
  223. ptr->s = agi->agi_root;
  224. }
  225. STATIC void
  226. xfs_finobt_init_ptr_from_cur(
  227. struct xfs_btree_cur *cur,
  228. union xfs_btree_ptr *ptr)
  229. {
  230. struct xfs_agi *agi = cur->bc_ag.agbp->b_addr;
  231. ASSERT(cur->bc_ag.pag->pag_agno == be32_to_cpu(agi->agi_seqno));
  232. ptr->s = agi->agi_free_root;
  233. }
  234. STATIC int64_t
  235. xfs_inobt_key_diff(
  236. struct xfs_btree_cur *cur,
  237. const union xfs_btree_key *key)
  238. {
  239. return (int64_t)be32_to_cpu(key->inobt.ir_startino) -
  240. cur->bc_rec.i.ir_startino;
  241. }
  242. STATIC int64_t
  243. xfs_inobt_diff_two_keys(
  244. struct xfs_btree_cur *cur,
  245. const union xfs_btree_key *k1,
  246. const union xfs_btree_key *k2,
  247. const union xfs_btree_key *mask)
  248. {
  249. ASSERT(!mask || mask->inobt.ir_startino);
  250. return (int64_t)be32_to_cpu(k1->inobt.ir_startino) -
  251. be32_to_cpu(k2->inobt.ir_startino);
  252. }
  253. static xfs_failaddr_t
  254. xfs_inobt_verify(
  255. struct xfs_buf *bp)
  256. {
  257. struct xfs_mount *mp = bp->b_mount;
  258. struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
  259. xfs_failaddr_t fa;
  260. unsigned int level;
  261. if (!xfs_verify_magic(bp, block->bb_magic))
  262. return __this_address;
  263. /*
  264. * During growfs operations, we can't verify the exact owner as the
  265. * perag is not fully initialised and hence not attached to the buffer.
  266. *
  267. * Similarly, during log recovery we will have a perag structure
  268. * attached, but the agi information will not yet have been initialised
  269. * from the on disk AGI. We don't currently use any of this information,
  270. * but beware of the landmine (i.e. need to check
  271. * xfs_perag_initialised_agi(pag)) if we ever do.
  272. */
  273. if (xfs_has_crc(mp)) {
  274. fa = xfs_btree_agblock_v5hdr_verify(bp);
  275. if (fa)
  276. return fa;
  277. }
  278. /* level verification */
  279. level = be16_to_cpu(block->bb_level);
  280. if (level >= M_IGEO(mp)->inobt_maxlevels)
  281. return __this_address;
  282. return xfs_btree_agblock_verify(bp,
  283. M_IGEO(mp)->inobt_mxr[level != 0]);
  284. }
  285. static void
  286. xfs_inobt_read_verify(
  287. struct xfs_buf *bp)
  288. {
  289. xfs_failaddr_t fa;
  290. if (!xfs_btree_agblock_verify_crc(bp))
  291. xfs_verifier_error(bp, -EFSBADCRC, __this_address);
  292. else {
  293. fa = xfs_inobt_verify(bp);
  294. if (fa)
  295. xfs_verifier_error(bp, -EFSCORRUPTED, fa);
  296. }
  297. if (bp->b_error)
  298. trace_xfs_btree_corrupt(bp, _RET_IP_);
  299. }
  300. static void
  301. xfs_inobt_write_verify(
  302. struct xfs_buf *bp)
  303. {
  304. xfs_failaddr_t fa;
  305. fa = xfs_inobt_verify(bp);
  306. if (fa) {
  307. trace_xfs_btree_corrupt(bp, _RET_IP_);
  308. xfs_verifier_error(bp, -EFSCORRUPTED, fa);
  309. return;
  310. }
  311. xfs_btree_agblock_calc_crc(bp);
  312. }
  313. const struct xfs_buf_ops xfs_inobt_buf_ops = {
  314. .name = "xfs_inobt",
  315. .magic = { cpu_to_be32(XFS_IBT_MAGIC), cpu_to_be32(XFS_IBT_CRC_MAGIC) },
  316. .verify_read = xfs_inobt_read_verify,
  317. .verify_write = xfs_inobt_write_verify,
  318. .verify_struct = xfs_inobt_verify,
  319. };
  320. const struct xfs_buf_ops xfs_finobt_buf_ops = {
  321. .name = "xfs_finobt",
  322. .magic = { cpu_to_be32(XFS_FIBT_MAGIC),
  323. cpu_to_be32(XFS_FIBT_CRC_MAGIC) },
  324. .verify_read = xfs_inobt_read_verify,
  325. .verify_write = xfs_inobt_write_verify,
  326. .verify_struct = xfs_inobt_verify,
  327. };
  328. STATIC int
  329. xfs_inobt_keys_inorder(
  330. struct xfs_btree_cur *cur,
  331. const union xfs_btree_key *k1,
  332. const union xfs_btree_key *k2)
  333. {
  334. return be32_to_cpu(k1->inobt.ir_startino) <
  335. be32_to_cpu(k2->inobt.ir_startino);
  336. }
  337. STATIC int
  338. xfs_inobt_recs_inorder(
  339. struct xfs_btree_cur *cur,
  340. const union xfs_btree_rec *r1,
  341. const union xfs_btree_rec *r2)
  342. {
  343. return be32_to_cpu(r1->inobt.ir_startino) + XFS_INODES_PER_CHUNK <=
  344. be32_to_cpu(r2->inobt.ir_startino);
  345. }
  346. STATIC enum xbtree_key_contig
  347. xfs_inobt_keys_contiguous(
  348. struct xfs_btree_cur *cur,
  349. const union xfs_btree_key *key1,
  350. const union xfs_btree_key *key2,
  351. const union xfs_btree_key *mask)
  352. {
  353. ASSERT(!mask || mask->inobt.ir_startino);
  354. return xbtree_key_contig(be32_to_cpu(key1->inobt.ir_startino),
  355. be32_to_cpu(key2->inobt.ir_startino));
  356. }
  357. const struct xfs_btree_ops xfs_inobt_ops = {
  358. .name = "ino",
  359. .type = XFS_BTREE_TYPE_AG,
  360. .rec_len = sizeof(xfs_inobt_rec_t),
  361. .key_len = sizeof(xfs_inobt_key_t),
  362. .ptr_len = XFS_BTREE_SHORT_PTR_LEN,
  363. .lru_refs = XFS_INO_BTREE_REF,
  364. .statoff = XFS_STATS_CALC_INDEX(xs_ibt_2),
  365. .sick_mask = XFS_SICK_AG_INOBT,
  366. .dup_cursor = xfs_inobt_dup_cursor,
  367. .set_root = xfs_inobt_set_root,
  368. .alloc_block = xfs_inobt_alloc_block,
  369. .free_block = xfs_inobt_free_block,
  370. .get_minrecs = xfs_inobt_get_minrecs,
  371. .get_maxrecs = xfs_inobt_get_maxrecs,
  372. .init_key_from_rec = xfs_inobt_init_key_from_rec,
  373. .init_high_key_from_rec = xfs_inobt_init_high_key_from_rec,
  374. .init_rec_from_cur = xfs_inobt_init_rec_from_cur,
  375. .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur,
  376. .key_diff = xfs_inobt_key_diff,
  377. .buf_ops = &xfs_inobt_buf_ops,
  378. .diff_two_keys = xfs_inobt_diff_two_keys,
  379. .keys_inorder = xfs_inobt_keys_inorder,
  380. .recs_inorder = xfs_inobt_recs_inorder,
  381. .keys_contiguous = xfs_inobt_keys_contiguous,
  382. };
  383. const struct xfs_btree_ops xfs_finobt_ops = {
  384. .name = "fino",
  385. .type = XFS_BTREE_TYPE_AG,
  386. .rec_len = sizeof(xfs_inobt_rec_t),
  387. .key_len = sizeof(xfs_inobt_key_t),
  388. .ptr_len = XFS_BTREE_SHORT_PTR_LEN,
  389. .lru_refs = XFS_INO_BTREE_REF,
  390. .statoff = XFS_STATS_CALC_INDEX(xs_fibt_2),
  391. .sick_mask = XFS_SICK_AG_FINOBT,
  392. .dup_cursor = xfs_finobt_dup_cursor,
  393. .set_root = xfs_finobt_set_root,
  394. .alloc_block = xfs_finobt_alloc_block,
  395. .free_block = xfs_finobt_free_block,
  396. .get_minrecs = xfs_inobt_get_minrecs,
  397. .get_maxrecs = xfs_inobt_get_maxrecs,
  398. .init_key_from_rec = xfs_inobt_init_key_from_rec,
  399. .init_high_key_from_rec = xfs_inobt_init_high_key_from_rec,
  400. .init_rec_from_cur = xfs_inobt_init_rec_from_cur,
  401. .init_ptr_from_cur = xfs_finobt_init_ptr_from_cur,
  402. .key_diff = xfs_inobt_key_diff,
  403. .buf_ops = &xfs_finobt_buf_ops,
  404. .diff_two_keys = xfs_inobt_diff_two_keys,
  405. .keys_inorder = xfs_inobt_keys_inorder,
  406. .recs_inorder = xfs_inobt_recs_inorder,
  407. .keys_contiguous = xfs_inobt_keys_contiguous,
  408. };
  409. /*
  410. * Create an inode btree cursor.
  411. *
  412. * For staging cursors tp and agbp are NULL.
  413. */
  414. struct xfs_btree_cur *
  415. xfs_inobt_init_cursor(
  416. struct xfs_perag *pag,
  417. struct xfs_trans *tp,
  418. struct xfs_buf *agbp)
  419. {
  420. struct xfs_mount *mp = pag->pag_mount;
  421. struct xfs_btree_cur *cur;
  422. cur = xfs_btree_alloc_cursor(mp, tp, &xfs_inobt_ops,
  423. M_IGEO(mp)->inobt_maxlevels, xfs_inobt_cur_cache);
  424. cur->bc_ag.pag = xfs_perag_hold(pag);
  425. cur->bc_ag.agbp = agbp;
  426. if (agbp) {
  427. struct xfs_agi *agi = agbp->b_addr;
  428. cur->bc_nlevels = be32_to_cpu(agi->agi_level);
  429. }
  430. return cur;
  431. }
  432. /*
  433. * Create a free inode btree cursor.
  434. *
  435. * For staging cursors tp and agbp are NULL.
  436. */
  437. struct xfs_btree_cur *
  438. xfs_finobt_init_cursor(
  439. struct xfs_perag *pag,
  440. struct xfs_trans *tp,
  441. struct xfs_buf *agbp)
  442. {
  443. struct xfs_mount *mp = pag->pag_mount;
  444. struct xfs_btree_cur *cur;
  445. cur = xfs_btree_alloc_cursor(mp, tp, &xfs_finobt_ops,
  446. M_IGEO(mp)->inobt_maxlevels, xfs_inobt_cur_cache);
  447. cur->bc_ag.pag = xfs_perag_hold(pag);
  448. cur->bc_ag.agbp = agbp;
  449. if (agbp) {
  450. struct xfs_agi *agi = agbp->b_addr;
  451. cur->bc_nlevels = be32_to_cpu(agi->agi_free_level);
  452. }
  453. return cur;
  454. }
  455. /*
  456. * Install a new inobt btree root. Caller is responsible for invalidating
  457. * and freeing the old btree blocks.
  458. */
  459. void
  460. xfs_inobt_commit_staged_btree(
  461. struct xfs_btree_cur *cur,
  462. struct xfs_trans *tp,
  463. struct xfs_buf *agbp)
  464. {
  465. struct xfs_agi *agi = agbp->b_addr;
  466. struct xbtree_afakeroot *afake = cur->bc_ag.afake;
  467. int fields;
  468. ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
  469. if (xfs_btree_is_ino(cur->bc_ops)) {
  470. fields = XFS_AGI_ROOT | XFS_AGI_LEVEL;
  471. agi->agi_root = cpu_to_be32(afake->af_root);
  472. agi->agi_level = cpu_to_be32(afake->af_levels);
  473. if (xfs_has_inobtcounts(cur->bc_mp)) {
  474. agi->agi_iblocks = cpu_to_be32(afake->af_blocks);
  475. fields |= XFS_AGI_IBLOCKS;
  476. }
  477. xfs_ialloc_log_agi(tp, agbp, fields);
  478. xfs_btree_commit_afakeroot(cur, tp, agbp);
  479. } else {
  480. fields = XFS_AGI_FREE_ROOT | XFS_AGI_FREE_LEVEL;
  481. agi->agi_free_root = cpu_to_be32(afake->af_root);
  482. agi->agi_free_level = cpu_to_be32(afake->af_levels);
  483. if (xfs_has_inobtcounts(cur->bc_mp)) {
  484. agi->agi_fblocks = cpu_to_be32(afake->af_blocks);
  485. fields |= XFS_AGI_IBLOCKS;
  486. }
  487. xfs_ialloc_log_agi(tp, agbp, fields);
  488. xfs_btree_commit_afakeroot(cur, tp, agbp);
  489. }
  490. }
  491. /* Calculate number of records in an inode btree block. */
  492. static inline unsigned int
  493. xfs_inobt_block_maxrecs(
  494. unsigned int blocklen,
  495. bool leaf)
  496. {
  497. if (leaf)
  498. return blocklen / sizeof(xfs_inobt_rec_t);
  499. return blocklen / (sizeof(xfs_inobt_key_t) + sizeof(xfs_inobt_ptr_t));
  500. }
  501. /*
  502. * Calculate number of records in an inobt btree block.
  503. */
  504. unsigned int
  505. xfs_inobt_maxrecs(
  506. struct xfs_mount *mp,
  507. unsigned int blocklen,
  508. bool leaf)
  509. {
  510. blocklen -= XFS_INOBT_BLOCK_LEN(mp);
  511. return xfs_inobt_block_maxrecs(blocklen, leaf);
  512. }
  513. /*
  514. * Maximum number of inode btree records per AG. Pretend that we can fill an
  515. * entire AG completely full of inodes except for the AG headers.
  516. */
  517. #define XFS_MAX_INODE_RECORDS \
  518. ((XFS_MAX_AG_BYTES - (4 * BBSIZE)) / XFS_DINODE_MIN_SIZE) / \
  519. XFS_INODES_PER_CHUNK
  520. /* Compute the max possible height for the inode btree. */
  521. static inline unsigned int
  522. xfs_inobt_maxlevels_ondisk(void)
  523. {
  524. unsigned int minrecs[2];
  525. unsigned int blocklen;
  526. blocklen = min(XFS_MIN_BLOCKSIZE - XFS_BTREE_SBLOCK_LEN,
  527. XFS_MIN_CRC_BLOCKSIZE - XFS_BTREE_SBLOCK_CRC_LEN);
  528. minrecs[0] = xfs_inobt_block_maxrecs(blocklen, true) / 2;
  529. minrecs[1] = xfs_inobt_block_maxrecs(blocklen, false) / 2;
  530. return xfs_btree_compute_maxlevels(minrecs, XFS_MAX_INODE_RECORDS);
  531. }
  532. /* Compute the max possible height for the free inode btree. */
  533. static inline unsigned int
  534. xfs_finobt_maxlevels_ondisk(void)
  535. {
  536. unsigned int minrecs[2];
  537. unsigned int blocklen;
  538. blocklen = XFS_MIN_CRC_BLOCKSIZE - XFS_BTREE_SBLOCK_CRC_LEN;
  539. minrecs[0] = xfs_inobt_block_maxrecs(blocklen, true) / 2;
  540. minrecs[1] = xfs_inobt_block_maxrecs(blocklen, false) / 2;
  541. return xfs_btree_compute_maxlevels(minrecs, XFS_MAX_INODE_RECORDS);
  542. }
  543. /* Compute the max possible height for either inode btree. */
  544. unsigned int
  545. xfs_iallocbt_maxlevels_ondisk(void)
  546. {
  547. return max(xfs_inobt_maxlevels_ondisk(),
  548. xfs_finobt_maxlevels_ondisk());
  549. }
  550. /*
  551. * Convert the inode record holemask to an inode allocation bitmap. The inode
  552. * allocation bitmap is inode granularity and specifies whether an inode is
  553. * physically allocated on disk (not whether the inode is considered allocated
  554. * or free by the fs).
  555. *
  556. * A bit value of 1 means the inode is allocated, a value of 0 means it is free.
  557. */
  558. uint64_t
  559. xfs_inobt_irec_to_allocmask(
  560. const struct xfs_inobt_rec_incore *rec)
  561. {
  562. uint64_t bitmap = 0;
  563. uint64_t inodespbit;
  564. int nextbit;
  565. uint allocbitmap;
  566. /*
  567. * The holemask has 16-bits for a 64 inode record. Therefore each
  568. * holemask bit represents multiple inodes. Create a mask of bits to set
  569. * in the allocmask for each holemask bit.
  570. */
  571. inodespbit = (1 << XFS_INODES_PER_HOLEMASK_BIT) - 1;
  572. /*
  573. * Allocated inodes are represented by 0 bits in holemask. Invert the 0
  574. * bits to 1 and convert to a uint so we can use xfs_next_bit(). Mask
  575. * anything beyond the 16 holemask bits since this casts to a larger
  576. * type.
  577. */
  578. allocbitmap = ~rec->ir_holemask & ((1 << XFS_INOBT_HOLEMASK_BITS) - 1);
  579. /*
  580. * allocbitmap is the inverted holemask so every set bit represents
  581. * allocated inodes. To expand from 16-bit holemask granularity to
  582. * 64-bit (e.g., bit-per-inode), set inodespbit bits in the target
  583. * bitmap for every holemask bit.
  584. */
  585. nextbit = xfs_next_bit(&allocbitmap, 1, 0);
  586. while (nextbit != -1) {
  587. ASSERT(nextbit < (sizeof(rec->ir_holemask) * NBBY));
  588. bitmap |= (inodespbit <<
  589. (nextbit * XFS_INODES_PER_HOLEMASK_BIT));
  590. nextbit = xfs_next_bit(&allocbitmap, 1, nextbit + 1);
  591. }
  592. return bitmap;
  593. }
  594. #if defined(DEBUG) || defined(XFS_WARN)
  595. /*
  596. * Verify that an in-core inode record has a valid inode count.
  597. */
  598. int
  599. xfs_inobt_rec_check_count(
  600. struct xfs_mount *mp,
  601. struct xfs_inobt_rec_incore *rec)
  602. {
  603. int inocount = 0;
  604. int nextbit = 0;
  605. uint64_t allocbmap;
  606. int wordsz;
  607. wordsz = sizeof(allocbmap) / sizeof(unsigned int);
  608. allocbmap = xfs_inobt_irec_to_allocmask(rec);
  609. nextbit = xfs_next_bit((uint *) &allocbmap, wordsz, nextbit);
  610. while (nextbit != -1) {
  611. inocount++;
  612. nextbit = xfs_next_bit((uint *) &allocbmap, wordsz,
  613. nextbit + 1);
  614. }
  615. if (inocount != rec->ir_count)
  616. return -EFSCORRUPTED;
  617. return 0;
  618. }
  619. #endif /* DEBUG */
  620. static xfs_extlen_t
  621. xfs_inobt_max_size(
  622. struct xfs_perag *pag)
  623. {
  624. struct xfs_mount *mp = pag->pag_mount;
  625. xfs_agblock_t agblocks = pag->block_count;
  626. /* Bail out if we're uninitialized, which can happen in mkfs. */
  627. if (M_IGEO(mp)->inobt_mxr[0] == 0)
  628. return 0;
  629. /*
  630. * The log is permanently allocated, so the space it occupies will
  631. * never be available for the kinds of things that would require btree
  632. * expansion. We therefore can pretend the space isn't there.
  633. */
  634. if (xfs_ag_contains_log(mp, pag->pag_agno))
  635. agblocks -= mp->m_sb.sb_logblocks;
  636. return xfs_btree_calc_size(M_IGEO(mp)->inobt_mnr,
  637. (uint64_t)agblocks * mp->m_sb.sb_inopblock /
  638. XFS_INODES_PER_CHUNK);
  639. }
  640. static int
  641. xfs_finobt_count_blocks(
  642. struct xfs_perag *pag,
  643. struct xfs_trans *tp,
  644. xfs_extlen_t *tree_blocks)
  645. {
  646. struct xfs_buf *agbp = NULL;
  647. struct xfs_btree_cur *cur;
  648. xfs_filblks_t blocks;
  649. int error;
  650. error = xfs_ialloc_read_agi(pag, tp, 0, &agbp);
  651. if (error)
  652. return error;
  653. cur = xfs_finobt_init_cursor(pag, tp, agbp);
  654. error = xfs_btree_count_blocks(cur, &blocks);
  655. xfs_btree_del_cursor(cur, error);
  656. xfs_trans_brelse(tp, agbp);
  657. *tree_blocks = blocks;
  658. return error;
  659. }
  660. /* Read finobt block count from AGI header. */
  661. static int
  662. xfs_finobt_read_blocks(
  663. struct xfs_perag *pag,
  664. struct xfs_trans *tp,
  665. xfs_extlen_t *tree_blocks)
  666. {
  667. struct xfs_buf *agbp;
  668. struct xfs_agi *agi;
  669. int error;
  670. error = xfs_ialloc_read_agi(pag, tp, 0, &agbp);
  671. if (error)
  672. return error;
  673. agi = agbp->b_addr;
  674. *tree_blocks = be32_to_cpu(agi->agi_fblocks);
  675. xfs_trans_brelse(tp, agbp);
  676. return 0;
  677. }
  678. /*
  679. * Figure out how many blocks to reserve and how many are used by this btree.
  680. */
  681. int
  682. xfs_finobt_calc_reserves(
  683. struct xfs_perag *pag,
  684. struct xfs_trans *tp,
  685. xfs_extlen_t *ask,
  686. xfs_extlen_t *used)
  687. {
  688. xfs_extlen_t tree_len = 0;
  689. int error;
  690. if (!xfs_has_finobt(pag->pag_mount))
  691. return 0;
  692. if (xfs_has_inobtcounts(pag->pag_mount))
  693. error = xfs_finobt_read_blocks(pag, tp, &tree_len);
  694. else
  695. error = xfs_finobt_count_blocks(pag, tp, &tree_len);
  696. if (error)
  697. return error;
  698. *ask += xfs_inobt_max_size(pag);
  699. *used += tree_len;
  700. return 0;
  701. }
  702. /* Calculate the inobt btree size for some records. */
  703. xfs_extlen_t
  704. xfs_iallocbt_calc_size(
  705. struct xfs_mount *mp,
  706. unsigned long long len)
  707. {
  708. return xfs_btree_calc_size(M_IGEO(mp)->inobt_mnr, len);
  709. }
  710. int __init
  711. xfs_inobt_init_cur_cache(void)
  712. {
  713. xfs_inobt_cur_cache = kmem_cache_create("xfs_inobt_cur",
  714. xfs_btree_cur_sizeof(xfs_inobt_maxlevels_ondisk()),
  715. 0, 0, NULL);
  716. if (!xfs_inobt_cur_cache)
  717. return -ENOMEM;
  718. return 0;
  719. }
  720. void
  721. xfs_inobt_destroy_cur_cache(void)
  722. {
  723. kmem_cache_destroy(xfs_inobt_cur_cache);
  724. xfs_inobt_cur_cache = NULL;
  725. }