fs/xfs/libxfs/xfs_dir2.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/libxfs/xfs_dir2.c
Extension
.c
Size
35531 bytes
Lines
1412
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_TEST_ERROR(mp, XFS_ERRTAG_DIR_INO_VALIDATE)) {
		xfs_warn(mp, "Invalid inode number 0x%Lx",
				(unsigned long long) ino);
		return -EFSCORRUPTED;
	}
	return 0;
}

/*
 * Initialize a directory with its "." and ".." entries.
 */
int
xfs_dir_init(
	xfs_trans_t	*tp,
	xfs_inode_t	*dp,
	xfs_inode_t	*pdp)
{
	struct xfs_da_args *args;
	int		error;

	ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
	error = xfs_dir_ino_validate(tp->t_mountp, I_INO(pdp));
	if (error)
		return error;

	args = kzalloc_obj(*args, GFP_KERNEL | __GFP_NOFAIL);
	if (!args)
		return -ENOMEM;

	args->geo = dp->i_mount->m_dir_geo;
	args->dp = dp;
	args->trans = tp;
	args->owner = I_INO(dp);
	error = xfs_dir2_sf_create(args, I_INO(pdp));
	kfree(args);
	return error;
}

enum xfs_dir2_fmt
xfs_dir2_format(
	struct xfs_da_args	*args,
	int			*error)
{
	struct xfs_inode	*dp = args->dp;
	struct xfs_mount	*mp = dp->i_mount;
	struct xfs_da_geometry	*geo = mp->m_dir_geo;
	xfs_fileoff_t		eof;

	xfs_assert_ilocked(dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL);

	*error = 0;
	if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL)
		return XFS_DIR2_FMT_SF;

	*error = xfs_bmap_last_offset(dp, &eof, XFS_DATA_FORK);
	if (*error)
		return XFS_DIR2_FMT_ERROR;

	if (eof == XFS_B_TO_FSB(mp, geo->blksize)) {
		if (XFS_IS_CORRUPT(mp, dp->i_disk_size != geo->blksize)) {
			xfs_da_mark_sick(args);
			*error = -EFSCORRUPTED;
			return XFS_DIR2_FMT_ERROR;
		}
		return XFS_DIR2_FMT_BLOCK;
	}
	if (eof == geo->leafblk + geo->fsbcount)
		return XFS_DIR2_FMT_LEAF;
	return XFS_DIR2_FMT_NODE;
}

int
xfs_dir_createname_args(
	struct xfs_da_args	*args)
{
	int			error;

	if (!args->inumber)
		args->op_flags |= XFS_DA_OP_JUSTCHECK;

	switch (xfs_dir2_format(args, &error)) {
	case XFS_DIR2_FMT_SF:
		return xfs_dir2_sf_addname(args);
	case XFS_DIR2_FMT_BLOCK:
		return xfs_dir2_block_addname(args);
	case XFS_DIR2_FMT_LEAF:
		return xfs_dir2_leaf_addname(args);
	case XFS_DIR2_FMT_NODE:
		return xfs_dir2_node_addname(args);
	default:

Annotation

Implementation Notes