fs/xfs/libxfs/xfs_rtrefcount_btree.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/libxfs/xfs_rtrefcount_btree.c
Extension
.c
Size
20631 bytes
Lines
758
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

xfs_rtrefcount_droot_space_calc(level, numrecs) > dsize) {
		xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
		return -EFSCORRUPTED;
	}

	broot = xfs_broot_alloc(xfs_ifork_ptr(ip, XFS_DATA_FORK),
			xfs_rtrefcount_broot_space_calc(mp, level, numrecs));
	if (broot)
		xfs_rtrefcountbt_from_disk(ip, dfp, dsize, broot);
	return 0;
}

/*
 * Convert in-memory form of btree root to on-disk form.
 */
void
xfs_rtrefcountbt_to_disk(
	struct xfs_mount		*mp,
	struct xfs_btree_block		*rblock,
	int				rblocklen,
	struct xfs_rtrefcount_root	*dblock,
	int				dblocklen)
{
	struct xfs_refcount_key	*fkp;
	__be64				*fpp;
	struct xfs_refcount_key	*tkp;
	__be64				*tpp;
	struct xfs_refcount_rec	*frp;
	struct xfs_refcount_rec	*trp;
	unsigned int			maxrecs;
	unsigned int			numrecs;

	ASSERT(rblock->bb_magic == cpu_to_be32(XFS_RTREFC_CRC_MAGIC));
	ASSERT(uuid_equal(&rblock->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid));
	ASSERT(rblock->bb_u.l.bb_blkno == cpu_to_be64(XFS_BUF_DADDR_NULL));
	ASSERT(rblock->bb_u.l.bb_leftsib == cpu_to_be64(NULLFSBLOCK));
	ASSERT(rblock->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK));

	dblock->bb_level = rblock->bb_level;
	dblock->bb_numrecs = rblock->bb_numrecs;

	if (be16_to_cpu(rblock->bb_level) > 0) {
		maxrecs = xfs_rtrefcountbt_droot_maxrecs(dblocklen, false);
		fkp = xfs_rtrefcount_key_addr(rblock, 1);
		tkp = xfs_rtrefcount_droot_key_addr(dblock, 1);
		fpp = xfs_rtrefcount_broot_ptr_addr(mp, rblock, 1, rblocklen);
		tpp = xfs_rtrefcount_droot_ptr_addr(dblock, 1, maxrecs);
		numrecs = be16_to_cpu(rblock->bb_numrecs);
		memcpy(tkp, fkp, 2 * sizeof(*fkp) * numrecs);
		memcpy(tpp, fpp, sizeof(*fpp) * numrecs);
	} else {
		frp = xfs_rtrefcount_rec_addr(rblock, 1);
		trp = xfs_rtrefcount_droot_rec_addr(dblock, 1);
		numrecs = be16_to_cpu(rblock->bb_numrecs);
		memcpy(trp, frp, sizeof(*frp) * numrecs);
	}
}

/* Flush a realtime reference count btree root out to disk. */
void
xfs_iflush_rtrefcount(
	struct xfs_inode	*ip,
	struct xfs_dinode	*dip)
{
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, XFS_DATA_FORK);
	struct xfs_rtrefcount_root *dfp = XFS_DFORK_PTR(dip, XFS_DATA_FORK);

	ASSERT(ifp->if_broot != NULL);
	ASSERT(ifp->if_broot_bytes > 0);
	ASSERT(xfs_rtrefcount_droot_space(ifp->if_broot) <=
			xfs_inode_fork_size(ip, XFS_DATA_FORK));
	xfs_rtrefcountbt_to_disk(ip->i_mount, ifp->if_broot,
			ifp->if_broot_bytes, dfp,
			XFS_DFORK_SIZE(dip, ip->i_mount, XFS_DATA_FORK));
}

/*
 * Create a realtime refcount btree inode.
 */
int
xfs_rtrefcountbt_create(
	struct xfs_rtgroup	*rtg,
	struct xfs_inode	*ip,
	struct xfs_trans	*tp,
	bool			init)
{
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, XFS_DATA_FORK);
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_btree_block	*broot;

Annotation

Implementation Notes