fs/xfs/libxfs/xfs_inode_fork.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/libxfs/xfs_inode_fork.c
Extension
.c
Size
19926 bytes
Lines
779
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 (fa) {
				xfs_inode_verifier_error(ip, -EFSCORRUPTED,
						"xfs_iformat_extents(2)",
						dp, sizeof(*dp), fa);
				xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
				return xfs_bmap_complain_bad_rec(ip, whichfork,
						fa, &new);
			}

			xfs_iext_insert(ip, &icur, &new, state);
			trace_xfs_read_extent(ip, &icur, state, _THIS_IP_);
			xfs_iext_next(ifp, &icur);
		}
	}
	return 0;
}

/*
 * The file has too many extents to fit into
 * the inode, so they are in B-tree format.
 * Allocate a buffer for the root of the B-tree
 * and copy the root into it.  The i_extents
 * field will remain NULL until all of the
 * extents are read in (when they are needed).
 */
STATIC int
xfs_iformat_btree(
	struct xfs_inode	*ip,
	struct xfs_dinode	*dip,
	int			whichfork)
{
	struct xfs_mount	*mp = ip->i_mount;
	xfs_bmdr_block_t	*dfp;
	struct xfs_ifork	*ifp;
	struct xfs_btree_block	*broot;
	int			nrecs;
	int			size;
	int			level;

	ifp = xfs_ifork_ptr(ip, whichfork);
	dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork);
	size = xfs_bmap_broot_space(mp, dfp);
	nrecs = be16_to_cpu(dfp->bb_numrecs);
	level = be16_to_cpu(dfp->bb_level);

	/*
	 * blow out if -- fork has less extents than can fit in
	 * fork (fork shouldn't be a btree format), root btree
	 * block has more records than can fit into the fork,
	 * or the number of extents is greater than the number of
	 * blocks.
	 */
	if (unlikely(ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork) ||
		     nrecs == 0 ||
		     xfs_bmdr_space_calc(nrecs) >
					XFS_DFORK_SIZE(dip, mp, whichfork) ||
		     ifp->if_nextents > ip->i_nblocks) ||
		     level == 0 || level > XFS_BM_MAXLEVELS(mp, whichfork)) {
		xfs_warn(mp, "corrupt inode %llu (btree).",
					(unsigned long long)I_INO(ip));
		xfs_inode_verifier_error(ip, -EFSCORRUPTED,
				"xfs_iformat_btree", dfp, size,
				__this_address);
		xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
		return -EFSCORRUPTED;
	}

	broot = xfs_broot_alloc(ifp, size);
	/*
	 * Copy and convert from the on-disk structure
	 * to the in-memory structure.
	 */
	xfs_bmdr_to_bmbt(ip, dfp, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork),
			 broot, size);

	ifp->if_bytes = 0;
	ifp->if_data = NULL;
	ifp->if_height = 0;
	return 0;
}

int
xfs_iformat_data_fork(
	struct xfs_inode	*ip,
	struct xfs_dinode	*dip)
{
	struct inode		*inode = VFS_I(ip);
	int			error;

	/*

Annotation

Implementation Notes