xfs_ialloc_btree.c 20 KB

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