cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xfs_ialloc_btree.c (20727B)


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