fs/xfs/libxfs/xfs_ialloc_btree.c

Source file repositories/reference/linux-study-clean/fs/xfs/libxfs/xfs_ialloc_btree.c

File Facts

System
Linux kernel
Corpus path
fs/xfs/libxfs/xfs_ialloc_btree.c
Extension
.c
Size
20821 bytes
Lines
839
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (xfs_has_inobtcounts(cur->bc_mp)) {
			agi->agi_iblocks = cpu_to_be32(afake->af_blocks);
			fields |= XFS_AGI_IBLOCKS;
		}
		xfs_ialloc_log_agi(tp, agbp, fields);
		xfs_btree_commit_afakeroot(cur, tp, agbp);
	} else {
		fields = XFS_AGI_FREE_ROOT | XFS_AGI_FREE_LEVEL;
		agi->agi_free_root = cpu_to_be32(afake->af_root);
		agi->agi_free_level = cpu_to_be32(afake->af_levels);
		if (xfs_has_inobtcounts(cur->bc_mp)) {
			agi->agi_fblocks = cpu_to_be32(afake->af_blocks);
			fields |= XFS_AGI_IBLOCKS;
		}
		xfs_ialloc_log_agi(tp, agbp, fields);
		xfs_btree_commit_afakeroot(cur, tp, agbp);
	}
}

/* Calculate number of records in an inode btree block. */
static inline unsigned int
xfs_inobt_block_maxrecs(
	unsigned int		blocklen,
	bool			leaf)
{
	if (leaf)
		return blocklen / sizeof(xfs_inobt_rec_t);
	return blocklen / (sizeof(xfs_inobt_key_t) + sizeof(xfs_inobt_ptr_t));
}

/*
 * Calculate number of records in an inobt btree block.
 */
unsigned int
xfs_inobt_maxrecs(
	struct xfs_mount	*mp,
	unsigned int		blocklen,
	bool			leaf)
{
	blocklen -= XFS_INOBT_BLOCK_LEN(mp);
	return xfs_inobt_block_maxrecs(blocklen, leaf);
}

/*
 * Maximum number of inode btree records per AG.  Pretend that we can fill an
 * entire AG completely full of inodes except for the AG headers.
 */
#define XFS_MAX_INODE_RECORDS \
	((XFS_MAX_AG_BYTES - (4 * BBSIZE)) / XFS_DINODE_MIN_SIZE) / \
			XFS_INODES_PER_CHUNK

/* Compute the max possible height for the inode btree. */
static inline unsigned int
xfs_inobt_maxlevels_ondisk(void)
{
	unsigned int		minrecs[2];
	unsigned int		blocklen;

	blocklen = min(XFS_MIN_BLOCKSIZE - XFS_BTREE_SBLOCK_LEN,
		       XFS_MIN_CRC_BLOCKSIZE - XFS_BTREE_SBLOCK_CRC_LEN);

	minrecs[0] = xfs_inobt_block_maxrecs(blocklen, true) / 2;
	minrecs[1] = xfs_inobt_block_maxrecs(blocklen, false) / 2;

	return xfs_btree_compute_maxlevels(minrecs, XFS_MAX_INODE_RECORDS);
}

/* Compute the max possible height for the free inode btree. */
static inline unsigned int
xfs_finobt_maxlevels_ondisk(void)
{
	unsigned int		minrecs[2];
	unsigned int		blocklen;

	blocklen = XFS_MIN_CRC_BLOCKSIZE - XFS_BTREE_SBLOCK_CRC_LEN;

	minrecs[0] = xfs_inobt_block_maxrecs(blocklen, true) / 2;
	minrecs[1] = xfs_inobt_block_maxrecs(blocklen, false) / 2;

	return xfs_btree_compute_maxlevels(minrecs, XFS_MAX_INODE_RECORDS);
}

/* Compute the max possible height for either inode btree. */
unsigned int
xfs_iallocbt_maxlevels_ondisk(void)
{
	return max(xfs_inobt_maxlevels_ondisk(),
		   xfs_finobt_maxlevels_ondisk());
}

Annotation

Implementation Notes