fs/xfs/xfs_attr_item.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/xfs_attr_item.c
Extension
.c
Size
32981 bytes
Lines
1208
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 (error) {
			xfs_irele(ip);
			return ERR_PTR(error);
		}
	}

	attr = kzalloc(sizeof(struct xfs_attr_intent) +
			sizeof(struct xfs_da_args), GFP_KERNEL | __GFP_NOFAIL);
	args = (struct xfs_da_args *)(attr + 1);

	attr->xattri_da_args = args;
	attr->xattri_op_flags = xfs_attr_log_item_op(attrp);

	/*
	 * We're reconstructing the deferred work state structure from the
	 * recovered log item.  Grab a reference to the name/value buffer and
	 * attach it to the new work state.
	 */
	attr->xattri_nameval = xfs_attri_log_nameval_get(nv);
	ASSERT(attr->xattri_nameval);

	args->dp = ip;
	args->geo = mp->m_attr_geo;
	args->whichfork = XFS_ATTR_FORK;
	args->name = nv->name.iov_base;
	args->namelen = nv->name.iov_len;
	args->new_name = nv->new_name.iov_base;
	args->new_namelen = nv->new_name.iov_len;
	args->value = nv->value.iov_base;
	args->valuelen = nv->value.iov_len;
	args->new_value = nv->new_value.iov_base;
	args->new_valuelen = nv->new_value.iov_len;
	args->attr_filter = attrp->alfi_attr_filter & XFS_ATTRI_FILTER_MASK;
	args->op_flags = XFS_DA_OP_RECOVERY | XFS_DA_OP_OKNOENT |
			 XFS_DA_OP_LOGGED;
	args->owner = I_INO(args->dp);
	xfs_attr_sethash(args);

	switch (xfs_attr_intent_op(attr)) {
	case XFS_ATTRI_OP_FLAGS_PPTR_SET:
	case XFS_ATTRI_OP_FLAGS_PPTR_REPLACE:
	case XFS_ATTRI_OP_FLAGS_SET:
	case XFS_ATTRI_OP_FLAGS_REPLACE:
		args->total = xfs_attr_calc_size(args, &local);
		if (xfs_inode_hasattr(args->dp))
			attr->xattri_dela_state = xfs_attr_init_replace_state(args);
		else
			attr->xattri_dela_state = xfs_attr_init_add_state(args);
		break;
	case XFS_ATTRI_OP_FLAGS_PPTR_REMOVE:
	case XFS_ATTRI_OP_FLAGS_REMOVE:
		attr->xattri_dela_state = xfs_attr_init_remove_state(args);
		break;
	}

	xfs_defer_add_item(dfp, &attr->xattri_list);
	*ipp = ip;
	return attr;
}

/*
 * Process an attr intent item that was recovered from the log.  We need to
 * delete the attr that it describes.
 */
STATIC int
xfs_attr_recover_work(
	struct xfs_defer_pending	*dfp,
	struct list_head		*capture_list)
{
	struct xfs_log_item		*lip = dfp->dfp_intent;
	struct xfs_attri_log_item	*attrip = ATTRI_ITEM(lip);
	struct xfs_attr_intent		*attr;
	struct xfs_mount		*mp = lip->li_log->l_mp;
	struct xfs_inode		*ip = NULL;
	struct xfs_da_args		*args;
	struct xfs_trans		*tp;
	struct xfs_trans_res		resv;
	struct xfs_attri_log_format	*attrp;
	struct xfs_attri_log_nameval	*nv = attrip->attri_nameval;
	int				error;
	unsigned int			total = 0;

	/*
	 * First check the validity of the attr described by the ATTRI.  If any
	 * are bad, then assume that all are bad and just toss the ATTRI.
	 */
	attrp = &attrip->attri_format;
	if (!xfs_attri_validate(mp, attrp) ||
	    !xfs_attr_namecheck(attrp->alfi_attr_filter, nv->name.iov_base,
				nv->name.iov_len))

Annotation

Implementation Notes