fs/xfs/xfs_handle.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/xfs_handle.c
Extension
.c
Size
21625 bytes
Lines
923
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

struct xfs_getparents_ctx {
	struct xfs_attr_list_context	context;
	struct xfs_getparents_by_handle	gph;

	/* File to target */
	struct xfs_inode		*ip;

	/* Internal buffer where we format records */
	void				*krecords;

	/* Last record filled out */
	struct xfs_getparents_rec	*lastrec;

	unsigned int			count;
};

static inline unsigned int
xfs_getparents_rec_sizeof(
	unsigned int		namelen)
{
	return round_up(sizeof(struct xfs_getparents_rec) + namelen + 1,
			sizeof(uint64_t));
}

static void
xfs_getparents_put_listent(
	struct xfs_attr_list_context	*context,
	int				flags,
	unsigned char			*name,
	int				namelen,
	void				*value,
	int				valuelen)
{
	struct xfs_getparents_ctx	*gpx =
		container_of(context, struct xfs_getparents_ctx, context);
	struct xfs_inode		*ip = context->dp;
	struct xfs_mount		*mp = ip->i_mount;
	struct xfs_getparents		*gp = &gpx->gph.gph_request;
	struct xfs_getparents_rec	*gpr = gpx->krecords + context->firstu;
	unsigned short			reclen =
		xfs_getparents_rec_sizeof(namelen);
	xfs_ino_t			ino;
	uint32_t			gen;
	int				error;

	if (!(flags & XFS_ATTR_PARENT))
		return;

	error = xfs_parent_from_attr(mp, flags, name, namelen, value, valuelen,
			&ino, &gen);
	if (error) {
		xfs_inode_mark_sick(ip, XFS_SICK_INO_PARENT);
		context->seen_enough = -EFSCORRUPTED;
		return;
	}

	/*
	 * We found a parent pointer, but we've filled up the buffer.  Signal
	 * to the caller that we did /not/ reach the end of the parent pointer
	 * recordset.
	 */
	if (context->firstu > context->bufsize - reclen) {
		context->seen_enough = 1;
		return;
	}

	/* Format the parent pointer directly into the caller buffer. */
	gpr->gpr_reclen = reclen;
	xfs_filehandle_init(mp, ino, gen, &gpr->gpr_parent);
	memcpy(gpr->gpr_name, name, namelen);
	gpr->gpr_name[namelen] = 0;

	trace_xfs_getparents_put_listent(ip, gp, context, gpr);

	context->firstu += reclen;
	gpx->count++;
	gpx->lastrec = gpr;
}

/* Expand the last record to fill the rest of the caller's buffer. */
static inline void
xfs_getparents_expand_lastrec(
	struct xfs_getparents_ctx	*gpx)
{
	struct xfs_getparents		*gp = &gpx->gph.gph_request;
	struct xfs_getparents_rec	*gpr = gpx->lastrec;

	if (!gpx->lastrec)
		gpr = gpx->krecords;

Annotation

Implementation Notes