fs/xfs/xfs_attr_list.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/xfs_attr_list.c
Extension
.c
Size
15163 bytes
Lines
600
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 (sbp->hash == cursor->hashval) {
			if (cursor->offset == count) {
				break;
			}
			count++;
		} else if (sbp->hash > cursor->hashval) {
			break;
		}
	}
	if (i == nsbuf)
		goto out;

	/*
	 * Loop putting entries into the user buffer.
	 */
	for ( ; i < nsbuf; i++, sbp++) {
		if (cursor->hashval != sbp->hash) {
			cursor->hashval = sbp->hash;
			cursor->offset = 0;
		}
		if (XFS_IS_CORRUPT(context->dp->i_mount,
				   !xfs_attr_namecheck(sbp->flags, sbp->name,
						       sbp->namelen))) {
			xfs_dirattr_mark_sick(context->dp, XFS_ATTR_FORK);
			error = -EFSCORRUPTED;
			goto out;
		}
		context->put_listent(context,
				     sbp->flags,
				     sbp->name,
				     sbp->namelen,
				     sbp->value,
				     sbp->valuelen);
		if (context->seen_enough)
			break;
		cursor->offset++;
	}
out:
	kfree(sbuf);
	return error;
}

/*
 * We didn't find the block & hash mentioned in the cursor state, so
 * walk down the attr btree looking for the hash.
 */
STATIC int
xfs_attr_node_list_lookup(
	struct xfs_attr_list_context	*context,
	struct xfs_attrlist_cursor_kern	*cursor,
	struct xfs_buf			**pbp)
{
	struct xfs_da3_icnode_hdr	nodehdr;
	struct xfs_da_intnode		*node;
	struct xfs_da_node_entry	*btree;
	struct xfs_inode		*dp = context->dp;
	struct xfs_mount		*mp = dp->i_mount;
	struct xfs_trans		*tp = context->tp;
	struct xfs_buf			*bp;
	xfs_failaddr_t			fa;
	int				i;
	int				error = 0;
	unsigned int			expected_level = 0;
	uint16_t			magic;

	ASSERT(*pbp == NULL);
	cursor->blkno = 0;
	for (;;) {
		error = xfs_da3_node_read(tp, dp, cursor->blkno, &bp,
				XFS_ATTR_FORK);
		if (error)
			return error;
		node = bp->b_addr;
		magic = be16_to_cpu(node->hdr.info.magic);
		if (magic == XFS_ATTR_LEAF_MAGIC ||
		    magic == XFS_ATTR3_LEAF_MAGIC)
			break;
		if (magic != XFS_DA_NODE_MAGIC &&
		    magic != XFS_DA3_NODE_MAGIC) {
			XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
					node, sizeof(*node));
			goto out_corruptbuf;
		}

		fa = xfs_da3_node_header_check(bp, I_INO(dp));
		if (fa)
			goto out_corruptbuf;

		xfs_da3_node_hdr_from_disk(mp, &nodehdr, node);

Annotation

Implementation Notes