// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
 * All Rights Reserved.
 */
#include "xfs.h"
#include "xfs_fs.h"
#include "xfs_shared.h"
#include "xfs_format.h"
#include "xfs_log_format.h"
#include "xfs_trans_resv.h"
#include "xfs_mount.h"
#include "xfs_defer.h"
#include "xfs_da_format.h"
#include "xfs_da_btree.h"
#include "xfs_attr_sf.h"
#include "xfs_inode.h"
#include "xfs_trans.h"
#include "xfs_bmap.h"
#include "xfs_bmap_btree.h"
#include "xfs_attr.h"
#include "xfs_attr_leaf.h"
#include "xfs_attr_remote.h"
#include "xfs_quota.h"
#include "xfs_trans_space.h"
#include "xfs_trace.h"

/*
 * xfs_attr.c
 *
 * Provide the external interfaces to manage attribute lists.
 */

/*========================================================================
 * Function prototypes for the kernel.
 *========================================================================*/

/*
 * Internal routines when attribute list fits inside the inode.
 */
STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);

/*
 * Internal routines when attribute list is one block.
 */
STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
STATIC int xfs_attr_leaf_hasname(struct xfs_da_args *args, struct xfs_buf **bp);
STATIC int xfs_attr_leaf_try_add(struct xfs_da_args *args, struct xfs_buf *bp);

/*
 * Internal routines when attribute list is more than one block.
 */
STATIC int xfs_attr_node_get(xfs_da_args_t *args);
STATIC void xfs_attr_restore_rmt_blk(struct xfs_da_args *args);
STATIC int xfs_attr_node_addname(struct xfs_delattr_context *dac);
STATIC int xfs_attr_node_addname_find_attr(struct xfs_delattr_context *dac);
STATIC int xfs_attr_node_addname_clear_incomplete(
				struct xfs_delattr_context *dac);
STATIC int xfs_attr_node_hasname(xfs_da_args_t *args,
				 struct xfs_da_state **state);
STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
STATIC int xfs_attr_set_iter(struct xfs_delattr_context *dac,
			     struct xfs_buf **leaf_bp);
STATIC int xfs_attr_node_removename(struct xfs_da_args *args,
				    struct xfs_da_state *state);

int
xfs_inode_hasattr(
	struct xfs_inode	*ip)
{
	if (!XFS_IFORK_Q(ip) ||
	    (ip->i_afp->if_format == XFS_DINODE_FMT_EXTENTS &&
	     ip->i_afp->if_nextents == 0))
		return 0;
	return 1;
}

/*
 * Returns true if the there is exactly only block in the attr fork, in which
 * case the attribute fork consists of a single leaf block entry.
 */
bool
xfs_attr_is_leaf(
	struct xfs_inode	*ip)
{
	struct xfs_ifork	*ifp = ip->i_afp;
	struct xfs_iext_cursor	icur;
	struct xfs_bmbt_irec	imap;

	if (ifp->if_nextents != 1 || ifp->if_format != XFS_DINODE_FMT_EXTENTS)
		return false;

	xfs_iext_first(ifp, &icur);
	xfs_iext_get_extent(ifp, &icur, &imap);
	return imap.br_startoff == 0 && imap.br_blockcount == 1;
}

/*========================================================================
 * Overall external interface routines.
 *========================================================================*/

/*
 * Retrieve an extended attribute and its value.  Must have ilock.
 * Returns 0 on successful retrieval, otherwise an error.
 */
int
xfs_attr_get_ilocked(
	struct xfs_da_args	*args)
{
	ASSERT(xfs_isilocked(args->dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));

	if (!xfs_inode_hasattr(args->dp))
		return -ENOATTR;

	if (args->dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL)
		return xfs_attr_shortform_getvalue(args);
	if (xfs_attr_is_leaf(args->dp))
		return xfs_attr_leaf_get(args);
	return xfs_attr_node_get(args);
}

/*
 * Retrieve an extended attribute by name, and its value if requested.
 *
 * If args->valuelen is zero, then the caller does not want the value, just an
 * indication whether the attribute exists and the size of the value if it
 * exists. The size is returned in args.valuelen.
 *
 * If args->value is NULL but args->valuelen is non-zero, allocate the buffer
 * for the value after existence of the attribute has been determined. The
 * caller always has to free args->value if it is set, no matter if this
 * function was successful or not.
 *
 * If the attribute is found, but exceeds the size limit set by the caller in
 * args->valuelen, return -ERANGE with the size of the attribute that was found
 * in args->valuelen.
 */
int
xfs_attr_get(
	struct xfs_da_args	*args)
{
	uint			lock_mode;
	int			error;

	XFS_STATS_INC(args->dp->i_mount, xs_attr_get);

	if (XFS_FORCED_SHUTDOWN(args->dp->i_mount))
		return -EIO;

	args->geo = args->dp->i_mount->m_attr_geo;
	args->whichfork = XFS_ATTR_FORK;
	args->hashval = xfs_da_hashname(args->name, args->namelen);

	/* Entirely possible to look up a name which doesn't exist */
	args->op_flags = XFS_DA_OP_OKNOENT;

	lock_mode = xfs_ilock_attr_map_shared(args->dp);
	error = xfs_attr_get_ilocked(args);
	xfs_iunlock(args->dp, lock_mode);

	return error;
}

/*
 * Calculate how many blocks we need for the new attribute,
 */
STATIC int
xfs_attr_calc_size(
	struct xfs_da_args	*args,
	int			*local)
{
	struct xfs_mount	*mp = args->dp->i_mount;
	int			size;
	int			nblks;

	/*
	 * Determine space new attribute will use, and if it would be
	 * "local" or "remote" (note: local != inline).
	 */
	size = xfs_attr_leaf_newentsize(args, local);
	nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
	if (*local) {
		if (size > (args->geo->blksize / 2)) {
			/* Double split possible */
			nblks *= 2;
		}
	} else {
		/*
		 * Out of line attribute, cannot double split, but
		 * make room for the attribute value itself.
		 */
		uint	dblocks = xfs_attr3_rmt_blocks(mp, args->valuelen);
		nblks += dblocks;
		nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
	}

	return nblks;
}

STATIC int
xfs_attr_try_sf_addname(
	struct xfs_inode	*dp,
	struct xfs_da_args	*args)
{

	int			error;

	/*
	 * Build initial attribute list (if required).
	 */
	if (dp->i_afp->if_format == XFS_DINODE_FMT_EXTENTS)
		xfs_attr_shortform_create(args);

	error = xfs_attr_shortform_addname(args);
	if (error == -ENOSPC)
		return error;

	/*
	 * Commit the shortform mods, and we're done.
	 * NOTE: this is also the error path (EEXIST, etc).
	 */
	if (!error && !(args->op_flags & XFS_DA_OP_NOTIME))
		xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);

	if (dp->i_mount->m_flags & XFS_MOUNT_WSYNC)
		xfs_trans_set_sync(args->trans);

	return error;
}

/*
 * Check to see if the attr should be upgraded from non-existent or shortform to
 * single-leaf-block attribute list.
 */
static inline bool
xfs_attr_is_shortform(
	struct xfs_inode    *ip)
{
	return ip->i_afp->if_format == XFS_DINODE_FMT_LOCAL ||
	       (ip->i_afp->if_format == XFS_DINODE_FMT_EXTENTS &&
		ip->i_afp->if_nextents == 0);
}

/*
 * Checks to see if a delayed attribute transaction should be rolled.  If so,
 * transaction is finished or rolled as needed.
 */
STATIC int
xfs_attr_trans_roll(
	struct xfs_delattr_context	*dac)
{
	struct xfs_da_args		*args = dac->da_args;
	int				error;

	if (dac->flags & XFS_DAC_DEFER_FINISH) {
		/*
		 * The caller wants us to finish all the deferred ops so that we
		 * avoid pinning the log tail with a large number of deferred
		 * ops.
		 */
		dac->flags &= ~XFS_DAC_DEFER_FINISH;
		error = xfs_defer_finish(&args->trans);
	} else
		error = xfs_trans_roll_inode(&args->trans, args->dp);

	return error;
}

/*
 * Set the attribute specified in @args.
 */
int
xfs_attr_set_args(
	struct xfs_da_args		*args)
{
	struct xfs_buf			*leaf_bp = NULL;
	int				error = 0;
	struct xfs_delattr_context	dac = {
		.da_args	= args,
	};

	do {
		error = xfs_attr_set_iter(&dac, &leaf_bp);
		if (error != -EAGAIN)
			break;

		error = xfs_attr_trans_roll(&dac);
		if (error) {
			if (leaf_bp)
				xfs_trans_brelse(args->trans, leaf_bp);
			return error;
		}
	} while (true);

	return error;
}

STATIC int
xfs_attr_sf_addname(
	struct xfs_delattr_context	*dac,
	struct xfs_buf			**leaf_bp)
{
	struct xfs_da_args		*args = dac->da_args;
	struct xfs_inode		*dp = args->dp;
	int				error = 0;

	/*
	 * Try to add the attr to the attribute list in the inode.
	 */
	error = xfs_attr_try_sf_addname(dp, args);

	/* Should only be 0, -EEXIST or -ENOSPC */
	if (error != -ENOSPC)
		return error;

	/*
	 * It won't fit in the shortform, transform to a leaf block.  GROT:
	 * another possible req'mt for a double-split btree op.
	 */
	error = xfs_attr_shortform_to_leaf(args, leaf_bp);
	if (error)
		return error;

	/*
	 * Prevent the leaf buffer from being unlocked so that a concurrent AIL
	 * push cannot grab the half-baked leaf buffer and run into problems
	 * with the write verifier.
	 */
	xfs_trans_bhold(args->trans, *leaf_bp);

	/*
	 * We're still in XFS_DAS_UNINIT state here.  We've converted
	 * the attr fork to leaf format and will restart with the leaf
	 * add.
	 */
	dac->flags |= XFS_DAC_DEFER_FINISH;
	return -EAGAIN;
}

/*
 * Set the attribute specified in @args.
 * This routine is meant to function as a delayed operation, and may return
 * -EAGAIN when the transaction needs to be rolled.  Calling functions will need
 * to handle this, and recall the function until a successful error code is
 * returned.
 */
int
xfs_attr_set_iter(
	struct xfs_delattr_context	*dac,
	struct xfs_buf			**leaf_bp)
{
	struct xfs_da_args              *args = dac->da_args;
	struct xfs_inode		*dp = args->dp;
	struct xfs_buf			*bp = NULL;
	int				forkoff, error = 0;

	/* State machine switch */
	switch (dac->dela_state) {
	case XFS_DAS_UNINIT:
		/*
		 * If the fork is shortform, attempt to add the attr. If there
		 * is no space, this converts to leaf format and returns
		 * -EAGAIN with the leaf buffer held across the roll. The caller
		 * will deal with a transaction roll error, but otherwise
		 * release the hold once we return with a clean transaction.
		 */
		if (xfs_attr_is_shortform(dp))
			return xfs_attr_sf_addname(dac, leaf_bp);
		if (*leaf_bp != NULL) {
			xfs_trans_bhold_release(args->trans, *leaf_bp);
			*leaf_bp = NULL;
		}

		if (xfs_attr_is_leaf(dp)) {
			error = xfs_attr_leaf_try_add(args, *leaf_bp);
			if (error == -ENOSPC) {
				error = xfs_attr3_leaf_to_node(args);
				if (error)
					return error;

				/*
				 * Finish any deferred work items and roll the
				 * transaction once more.  The goal here is to
				 * call node_addname with the inode and
				 * transaction in the same state (inode locked
				 * and joined, transaction clean) no matter how
				 * we got to this step.
				 *
				 * At this point, we are still in
				 * XFS_DAS_UNINIT, but when we come back, we'll
				 * be a node, so we'll fall down into the node
				 * handling code below
				 */
				dac->flags |= XFS_DAC_DEFER_FINISH;
				return -EAGAIN;
			} else if (error) {
				return error;
			}

			dac->dela_state = XFS_DAS_FOUND_LBLK;
		} else {
			error = xfs_attr_node_addname_find_attr(dac);
			if (error)
				return error;

			error = xfs_attr_node_addname(dac);
			if (error)
				return error;

			dac->dela_state = XFS_DAS_FOUND_NBLK;
		}
		return -EAGAIN;
	case XFS_DAS_FOUND_LBLK:
		/*
		 * If there was an out-of-line value, allocate the blocks we
		 * identified for its storage and copy the value.  This is done
		 * after we create the attribute so that we don't overflow the
		 * maximum size of a transaction and/or hit a deadlock.
		 */

		/* Open coded xfs_attr_rmtval_set without trans handling */
		if ((dac->flags & XFS_DAC_LEAF_ADDNAME_INIT) == 0) {
			dac->flags |= XFS_DAC_LEAF_ADDNAME_INIT;
			if (args->rmtblkno > 0) {
				error = xfs_attr_rmtval_find_space(dac);
				if (error)
					return error;
			}
		}

		/*
		 * Repeat allocating remote blocks for the attr value until
		 * blkcnt drops to zero.
		 */
		if (dac->blkcnt > 0) {
			error = xfs_attr_rmtval_set_blk(dac);
			if (error)
				return error;
			return -EAGAIN;
		}

		error = xfs_attr_rmtval_set_value(args);
		if (error)
			return error;

		/*
		 * If this is not a rename, clear the incomplete flag and we're
		 * done.
		 */
		if (!(args->op_flags & XFS_DA_OP_RENAME)) {
			if (args->rmtblkno > 0)
				error = xfs_attr3_leaf_clearflag(args);
			return error;
		}

		/*
		 * If this is an atomic rename operation, we must "flip" the
		 * incomplete flags on the "new" and "old" attribute/value pairs
		 * so that one disappears and one appears atomically.  Then we
		 * must remove the "old" attribute/value pair.
		 *
		 * In a separate transaction, set the incomplete flag on the
		 * "old" attr and clear the incomplete flag on the "new" attr.
		 */
		error = xfs_attr3_leaf_flipflags(args);
		if (error)
			return error;
		/*
		 * Commit the flag value change and start the next trans in
		 * series.
		 */
		dac->dela_state = XFS_DAS_FLIP_LFLAG;
		return -EAGAIN;
	case XFS_DAS_FLIP_LFLAG:
		/*
		 * Dismantle the "old" attribute/value pair by removing a
		 * "remote" value (if it exists).
		 */
		xfs_attr_restore_rmt_blk(args);
		error = xfs_attr_rmtval_invalidate(args);
		if (error)
			return error;

		fallthrough;
	case XFS_DAS_RM_LBLK:
		/* Set state in case xfs_attr_rmtval_remove returns -EAGAIN */
		dac->dela_state = XFS_DAS_RM_LBLK;
		if (args->rmtblkno) {
			error = __xfs_attr_rmtval_remove(dac);
			if (error)
				return error;

			dac->dela_state = XFS_DAS_RD_LEAF;
			return -EAGAIN;
		}

		fallthrough;
	case XFS_DAS_RD_LEAF:
		/*
		 * This is the last step for leaf format. Read the block with
		 * the old attr, remove the old attr, check for shortform
		 * conversion and return.
		 */
		error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno,
					   &bp);
		if (error)
			return error;

		xfs_attr3_leaf_remove(bp, args);

		forkoff = xfs_attr_shortform_allfit(bp, dp);
		if (forkoff)
			error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
			/* bp is gone due to xfs_da_shrink_inode */

		return error;

	case XFS_DAS_FOUND_NBLK:
		/*
		 * Find space for remote blocks and fall into the allocation
		 * state.
		 */
		if (args->rmtblkno > 0) {
			error = xfs_attr_rmtval_find_space(dac);
			if (error)
				return error;
		}

		fallthrough;
	case XFS_DAS_ALLOC_NODE:
		/*
		 * If there was an out-of-line value, allocate the blocks we
		 * identified for its storage and copy the value.  This is done
		 * after we create the attribute so that we don't overflow the
		 * maximum size of a transaction and/or hit a deadlock.
		 */
		dac->dela_state = XFS_DAS_ALLOC_NODE;
		if (args->rmtblkno > 0) {
			if (dac->blkcnt > 0) {
				error = xfs_attr_rmtval_set_blk(dac);
				if (error)
					return error;
				return -EAGAIN;
			}

			error = xfs_attr_rmtval_set_value(args);
			if (error)
				return error;
		}

		/*
		 * If this was not a rename, clear the incomplete flag and we're
		 * done.
		 */
		if (!(args->op_flags & XFS_DA_OP_RENAME)) {
			if (args->rmtblkno > 0)
				error = xfs_attr3_leaf_clearflag(args);
			goto out;
		}

		/*
		 * If this is an atomic rename operation, we must "flip" the
		 * incomplete flags on the "new" and "old" attribute/value pairs
		 * so that one disappears and one appears atomically.  Then we
		 * must remove the "old" attribute/value pair.
		 *
		 * In a separate transaction, set the incomplete flag on the
		 * "old" attr and clear the incomplete flag on the "new" attr.
		 */
		error = xfs_attr3_leaf_flipflags(args);
		if (error)
			goto out;
		/*
		 * Commit the flag value change and start the next trans in
		 * series
		 */
		dac->dela_state = XFS_DAS_FLIP_NFLAG;
		return -EAGAIN;

	case XFS_DAS_FLIP_NFLAG:
		/*
		 * Dismantle the "old" attribute/value pair by removing a
		 * "remote" value (if it exists).
		 */
		xfs_attr_restore_rmt_blk(args);

		error = xfs_attr_rmtval_invalidate(args);
		if (error)
			return error;

		fallthrough;
	case XFS_DAS_RM_NBLK:
		/* Set state in case xfs_attr_rmtval_remove returns -EAGAIN */
		dac->dela_state = XFS_DAS_RM_NBLK;
		if (args->rmtblkno) {
			error = __xfs_attr_rmtval_remove(dac);
			if (error)
				return error;

			dac->dela_state = XFS_DAS_CLR_FLAG;
			return -EAGAIN;
		}

		fallthrough;
	case XFS_DAS_CLR_FLAG:
		/*
		 * The last state for node format. Look up the old attr and
		 * remove it.
		 */
		error = xfs_attr_node_addname_clear_incomplete(dac);
		break;
	default:
		ASSERT(0);
		break;
	}
out:
	return error;
}


/*
 * Return EEXIST if attr is found, or ENOATTR if not
 */
int
xfs_has_attr(
	struct xfs_da_args	*args)
{
	struct xfs_inode	*dp = args->dp;
	struct xfs_buf		*bp = NULL;
	int			error;

	if (!xfs_inode_hasattr(dp))
		return -ENOATTR;

	if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL)
		return xfs_attr_sf_findname(args, NULL, NULL);

	if (xfs_attr_is_leaf(dp)) {
		error = xfs_attr_leaf_hasname(args, &bp);

		if (bp)
			xfs_trans_brelse(args->trans, bp);

		return error;
	}

	return xfs_attr_node_hasname(args, NULL);
}

/*
 * Remove the attribute specified in @args.
 */
int
xfs_attr_remove_args(
	struct xfs_da_args	*args)
{
	int				error;
	struct xfs_delattr_context	dac = {
		.da_args	= args,
	};

	do {
		error = xfs_attr_remove_iter(&dac);
		if (error != -EAGAIN)
			break;

		error = xfs_attr_trans_roll(&dac);
		if (error)
			return error;

	} while (true);

	return error;
}

/*
 * Note: If args->value is NULL the attribute will be removed, just like the
 * Linux ->setattr API.
 */
int
xfs_attr_set(
	struct xfs_da_args	*args)
{
	struct xfs_inode	*dp = args->dp;
	struct xfs_mount	*mp = dp->i_mount;
	struct xfs_trans_res	tres;
	bool			rsvd = (args->attr_filter & XFS_ATTR_ROOT);
	int			error, local;
	int			rmt_blks = 0;
	unsigned int		total;

	if (XFS_FORCED_SHUTDOWN(dp->i_mount))
		return -EIO;

	error = xfs_qm_dqattach(dp);
	if (error)
		return error;

	args->geo = mp->m_attr_geo;
	args->whichfork = XFS_ATTR_FORK;
	args->hashval = xfs_da_hashname(args->name, args->namelen);

	/*
	 * We have no control over the attribute names that userspace passes us
	 * to remove, so we have to allow the name lookup prior to attribute
	 * removal to fail as well.
	 */
	args->op_flags = XFS_DA_OP_OKNOENT;

	if (args->value) {
		XFS_STATS_INC(mp, xs_attr_set);

		args->op_flags |= XFS_DA_OP_ADDNAME;
		args->total = xfs_attr_calc_size(args, &local);

		/*
		 * If the inode doesn't have an attribute fork, add one.
		 * (inode must not be locked when we call this routine)
		 */
		if (XFS_IFORK_Q(dp) == 0) {
			int sf_size = sizeof(struct xfs_attr_sf_hdr) +
				xfs_attr_sf_entsize_byname(args->namelen,
						args->valuelen);

			error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
			if (error)
				return error;
		}

		tres.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
				 M_RES(mp)->tr_attrsetrt.tr_logres *
					args->total;
		tres.tr_logcount = XFS_ATTRSET_LOG_COUNT;
		tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
		total = args->total;

		if (!local)
			rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
	} else {
		XFS_STATS_INC(mp, xs_attr_remove);

		tres = M_RES(mp)->tr_attrrm;
		total = XFS_ATTRRM_SPACE_RES(mp);
		rmt_blks = xfs_attr3_rmt_blocks(mp, XFS_XATTR_SIZE_MAX);
	}

	/*
	 * Root fork attributes can use reserved data blocks for this
	 * operation if necessary
	 */
	error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);
	if (error)
		return error;

	if (args->value || xfs_inode_hasattr(dp)) {
		error = xfs_iext_count_may_overflow(dp, XFS_ATTR_FORK,
				XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
		if (error)
			goto out_trans_cancel;
	}

	if (args->value) {
		error = xfs_has_attr(args);
		if (error == -EEXIST && (args->attr_flags & XATTR_CREATE))
			goto out_trans_cancel;
		if (error == -ENOATTR && (args->attr_flags & XATTR_REPLACE))
			goto out_trans_cancel;
		if (error != -ENOATTR && error != -EEXIST)
			goto out_trans_cancel;

		error = xfs_attr_set_args(args);
		if (error)
			goto out_trans_cancel;
		/* shortform attribute has already been committed */
		if (!args->trans)
			goto out_unlock;
	} else {
		error = xfs_has_attr(args);
		if (error != -EEXIST)
			goto out_trans_cancel;

		error = xfs_attr_remove_args(args);
		if (error)
			goto out_trans_cancel;
	}

	/*
	 * If this is a synchronous mount, make sure that the
	 * transaction goes to disk before returning to the user.
	 */
	if (mp->m_flags & XFS_MOUNT_WSYNC)
		xfs_trans_set_sync(args->trans);

	if (!(args->op_flags & XFS_DA_OP_NOTIME))
		xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);

	/*
	 * Commit the last in the sequence of transactions.
	 */
	xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
	error = xfs_trans_commit(args->trans);
out_unlock:
	xfs_iunlock(dp, XFS_ILOCK_EXCL);
	return error;

out_trans_cancel:
	if (args->trans)
		xfs_trans_cancel(args->trans);
	goto out_unlock;
}

/*========================================================================
 * External routines when attribute list is inside the inode
 *========================================================================*/

static inline int xfs_attr_sf_totsize(struct xfs_inode *dp)
{
	struct xfs_attr_shortform *sf;

	sf = (struct xfs_attr_shortform *)dp->i_afp->if_u1.if_data;
	return be16_to_cpu(sf->hdr.totsize);
}

/*
 * Add a name to the shortform attribute list structure
 * This is the external routine.
 */
STATIC int
xfs_attr_shortform_addname(xfs_da_args_t *args)
{
	int newsize, forkoff, retval;

	trace_xfs_attr_sf_addname(args);

	retval = xfs_attr_shortform_lookup(args);
	if (retval == -ENOATTR && (args->attr_flags & XATTR_REPLACE))
		return retval;
	if (retval == -EEXIST) {
		if (args->attr_flags & XATTR_CREATE)
			return retval;
		retval = xfs_attr_sf_removename(args);
		if (retval)
			return retval;
		/*
		 * Since we have removed the old attr, clear ATTR_REPLACE so
		 * that the leaf format add routine won't trip over the attr
		 * not being around.
		 */
		args->attr_flags &= ~XATTR_REPLACE;
	}

	if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
	    args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
		return -ENOSPC;

	newsize = xfs_attr_sf_totsize(args->dp);
	newsize += xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);

	forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
	if (!forkoff)
		return -ENOSPC;

	xfs_attr_shortform_add(args, forkoff);
	return 0;
}


/*========================================================================
 * External routines when attribute list is one block
 *========================================================================*/

/* Store info about a remote block */
STATIC void
xfs_attr_save_rmt_blk(
	struct xfs_da_args	*args)
{
	args->blkno2 = args->blkno;
	args->index2 = args->index;
	args->rmtblkno2 = args->rmtblkno;
	args->rmtblkcnt2 = args->rmtblkcnt;
	args->rmtvaluelen2 = args->rmtvaluelen;
}

/* Set stored info about a remote block */
STATIC void
xfs_attr_restore_rmt_blk(
	struct xfs_da_args	*args)
{
	args->blkno = args->blkno2;
	args->index = args->index2;
	args->rmtblkno = args->rmtblkno2;
	args->rmtblkcnt = args->rmtblkcnt2;
	args->rmtvaluelen = args->rmtvaluelen2;
}

/*
 * Tries to add an attribute to an inode in leaf form
 *
 * This function is meant to execute as part of a delayed operation and leaves
 * the transaction handling to the caller.  On success the attribute is added
 * and the inode and transaction are left dirty.  If there is not enough space,
 * the attr data is converted to node format and -ENOSPC is returned. Caller is
 * responsible for handling the dirty inode and transaction or adding the attr
 * in node format.
 */
STATIC int
xfs_attr_leaf_try_add(
	struct xfs_da_args	*args,
	struct xfs_buf		*bp)
{
	int			retval;

	/*
	 * Look up the given attribute in the leaf block.  Figure out if
	 * the given flags produce an error or call for an atomic rename.
	 */
	retval = xfs_attr_leaf_hasname(args, &bp);
	if (retval != -ENOATTR && retval != -EEXIST)
		return retval;
	if (retval == -ENOATTR && (args->attr_flags & XATTR_REPLACE))
		goto out_brelse;
	if (retval == -EEXIST) {
		if (args->attr_flags & XATTR_CREATE)
			goto out_brelse;

		trace_xfs_attr_leaf_replace(args);

		/* save the attribute state for later removal*/
		args->op_flags |= XFS_DA_OP_RENAME;	/* an atomic rename */
		xfs_attr_save_rmt_blk(args);

		/*
		 * clear the remote attr state now that it is saved so that the
		 * values reflect the state of the attribute we are about to
		 * add, not the attribute we just found and will remove later.
		 */
		args->rmtblkno = 0;
		args->rmtblkcnt = 0;
		args->rmtvaluelen = 0;
	}

	/*
	 * Add the attribute to the leaf block
	 */
	return xfs_attr3_leaf_add(bp, args);

out_brelse:
	xfs_trans_brelse(args->trans, bp);
	return retval;
}

/*
 * Return EEXIST if attr is found, or ENOATTR if not
 */
STATIC int
xfs_attr_leaf_hasname(
	struct xfs_da_args	*args,
	struct xfs_buf		**bp)
{
	int                     error = 0;

	error = xfs_attr3_leaf_read(args->trans, args->dp, 0, bp);
	if (error)
		return error;

	error = xfs_attr3_leaf_lookup_int(*bp, args);
	if (error != -ENOATTR && error != -EEXIST)
		xfs_trans_brelse(args->trans, *bp);

	return error;
}

/*
 * Remove a name from the leaf attribute list structure
 *
 * This leaf block cannot have a "remote" value, we only call this routine
 * if bmap_one_block() says there is only one block (ie: no remote blks).
 */
STATIC int
xfs_attr_leaf_removename(
	struct xfs_da_args	*args)
{
	struct xfs_inode	*dp;
	struct xfs_buf		*bp;
	int			error, forkoff;

	trace_xfs_attr_leaf_removename(args);

	/*
	 * Remove the attribute.
	 */
	dp = args->dp;

	error = xfs_attr_leaf_hasname(args, &bp);

	if (error == -ENOATTR) {
		xfs_trans_brelse(args->trans, bp);
		return error;
	} else if (error != -EEXIST)
		return error;

	xfs_attr3_leaf_remove(bp, args);

	/*
	 * If the result is small enough, shrink it all into the inode.
	 */
	forkoff = xfs_attr_shortform_allfit(bp, dp);
	if (forkoff)
		return xfs_attr3_leaf_to_shortform(bp, args, forkoff);
		/* bp is gone due to xfs_da_shrink_inode */

	return 0;
}

/*
 * Look up a name in a leaf attribute list structure.
 *
 * This leaf block cannot have a "remote" value, we only call this routine
 * if bmap_one_block() says there is only one block (ie: no remote blks).
 *
 * Returns 0 on successful retrieval, otherwise an error.
 */
STATIC int
xfs_attr_leaf_get(xfs_da_args_t *args)
{
	struct xfs_buf *bp;
	int error;

	trace_xfs_attr_leaf_get(args);

	error = xfs_attr_leaf_hasname(args, &bp);

	if (error == -ENOATTR)  {
		xfs_trans_brelse(args->trans, bp);
		return error;
	} else if (error != -EEXIST)
		return error;


	error = xfs_attr3_leaf_getvalue(bp, args);
	xfs_trans_brelse(args->trans, bp);
	return error;
}

/*
 * Return EEXIST if attr is found, or ENOATTR if not
 * statep: If not null is set to point at the found state.  Caller will
 *         be responsible for freeing the state in this case.
 */
STATIC int
xfs_attr_node_hasname(
	struct xfs_da_args	*args,
	struct xfs_da_state	**statep)
{
	struct xfs_da_state	*state;
	int			retval, error;

	state = xfs_da_state_alloc(args);
	if (statep != NULL)
		*statep = NULL;

	/*
	 * Search to see if name exists, and get back a pointer to it.
	 */
	error = xfs_da3_node_lookup_int(state, &retval);
	if (error) {
		xfs_da_state_free(state);
		return error;
	}

	if (statep != NULL)
		*statep = state;
	else
		xfs_da_state_free(state);
	return retval;
}

/*========================================================================
 * External routines when attribute list size > geo->blksize
 *========================================================================*/

STATIC int
xfs_attr_node_addname_find_attr(
	struct xfs_delattr_context	*dac)
{
	struct xfs_da_args		*args = dac->da_args;
	int				retval;

	/*
	 * Search to see if name already exists, and get back a pointer
	 * to where it should go.
	 */
	retval = xfs_attr_node_hasname(args, &dac->da_state);
	if (retval != -ENOATTR && retval != -EEXIST)
		return retval;

	if (retval == -ENOATTR && (args->attr_flags & XATTR_REPLACE))
		goto error;
	if (retval == -EEXIST) {
		if (args->attr_flags & XATTR_CREATE)
			goto error;

		trace_xfs_attr_node_replace(args);

		/* save the attribute state for later removal*/
		args->op_flags |= XFS_DA_OP_RENAME;	/* atomic rename op */
		xfs_attr_save_rmt_blk(args);

		/*
		 * clear the remote attr state now that it is saved so that the
		 * values reflect the state of the attribute we are about to
		 * add, not the attribute we just found and will remove later.
		 */
		args->rmtblkno = 0;
		args->rmtblkcnt = 0;
		args->rmtvaluelen = 0;
	}

	return 0;
error:
	if (dac->da_state)
		xfs_da_state_free(dac->da_state);
	return retval;
}

/*
 * Add a name to a Btree-format attribute list.
 *
 * This will involve walking down the Btree, and may involve splitting
 * leaf nodes and even splitting intermediate nodes up to and including
 * the root node (a special case of an intermediate node).
 *
 * "Remote" attribute values confuse the issue and atomic rename operations
 * add a whole extra layer of confusion on top of that.
 *
 * This routine is meant to function as a delayed operation, and may return
 * -EAGAIN when the transaction needs to be rolled.  Calling functions will need
 * to handle this, and recall the function until a successful error code is
 *returned.
 */
STATIC int
xfs_attr_node_addname(
	struct xfs_delattr_context	*dac)
{
	struct xfs_da_args		*args = dac->da_args;
	struct xfs_da_state		*state = dac->da_state;
	struct xfs_da_state_blk		*blk;
	int				error;

	trace_xfs_attr_node_addname(args);

	blk = &state->path.blk[state->path.active-1];
	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);

	error = xfs_attr3_leaf_add(blk->bp, state->args);
	if (error == -ENOSPC) {
		if (state->path.active == 1) {
			/*
			 * Its really a single leaf node, but it had
			 * out-of-line values so it looked like it *might*
			 * have been a b-tree.
			 */
			xfs_da_state_free(state);
			state = NULL;
			error = xfs_attr3_leaf_to_node(args);
			if (error)
				goto out;

			/*
			 * Now that we have converted the leaf to a node, we can
			 * roll the transaction, and try xfs_attr3_leaf_add
			 * again on re-entry.  No need to set dela_state to do
			 * this. dela_state is still unset by this function at
			 * this point.
			 */
			dac->flags |= XFS_DAC_DEFER_FINISH;
			return -EAGAIN;
		}

		/*
		 * Split as many Btree elements as required.
		 * This code tracks the new and old attr's location
		 * in the index/blkno/rmtblkno/rmtblkcnt fields and
		 * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields.
		 */
		error = xfs_da3_split(state);
		if (error)
			goto out;
		dac->flags |= XFS_DAC_DEFER_FINISH;
	} else {
		/*
		 * Addition succeeded, update Btree hashvals.
		 */
		xfs_da3_fixhashpath(state, &state->path);
	}

out:
	if (state)
		xfs_da_state_free(state);
	return error;
}


STATIC int
xfs_attr_node_addname_clear_incomplete(
	struct xfs_delattr_context	*dac)
{
	struct xfs_da_args		*args = dac->da_args;
	struct xfs_da_state		*state = NULL;
	int				retval = 0;
	int				error = 0;

	/*
	 * Re-find the "old" attribute entry after any split ops. The INCOMPLETE
	 * flag means that we will find the "old" attr, not the "new" one.
	 */
	args->attr_filter |= XFS_ATTR_INCOMPLETE;
	state = xfs_da_state_alloc(args);
	state->inleaf = 0;
	error = xfs_da3_node_lookup_int(state, &retval);
	if (error)
		goto out;

	error = xfs_attr_node_removename(args, state);

	/*
	 * Check to see if the tree needs to be collapsed.
	 */
	if (retval && (state->path.active > 1)) {
		error = xfs_da3_join(state);
		if (error)
			goto out;
	}
	retval = error = 0;

out:
	if (state)
		xfs_da_state_free(state);
	if (error)
		return error;
	return retval;
}

/*
 * Shrink an attribute from leaf to shortform
 */
STATIC int
xfs_attr_node_shrink(
	struct xfs_da_args	*args,
	struct xfs_da_state     *state)
{
	struct xfs_inode	*dp = args->dp;
	int			error, forkoff;
	struct xfs_buf		*bp;

	/*
	 * Have to get rid of the copy of this dabuf in the state.
	 */
	ASSERT(state->path.active == 1);
	ASSERT(state->path.blk[0].bp);
	state->path.blk[0].bp = NULL;

	error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp);
	if (error)
		return error;

	forkoff = xfs_attr_shortform_allfit(bp, dp);
	if (forkoff) {
		error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
		/* bp is gone due to xfs_da_shrink_inode */
	} else
		xfs_trans_brelse(args->trans, bp);

	return error;
}

/*
 * Mark an attribute entry INCOMPLETE and save pointers to the relevant buffers
 * for later deletion of the entry.
 */
STATIC int
xfs_attr_leaf_mark_incomplete(
	struct xfs_da_args	*args,
	struct xfs_da_state	*state)
{
	int			error;

	/*
	 * Fill in disk block numbers in the state structure
	 * so that we can get the buffers back after we commit
	 * several transactions in the following calls.
	 */
	error = xfs_attr_fillstate(state);
	if (error)
		return error;

	/*
	 * Mark the attribute as INCOMPLETE
	 */
	return xfs_attr3_leaf_setflag(args);
}

/*
 * Initial setup for xfs_attr_node_removename.  Make sure the attr is there and
 * the blocks are valid.  Attr keys with remote blocks will be marked
 * incomplete.
 */
STATIC
int xfs_attr_node_removename_setup(
	struct xfs_delattr_context	*dac)
{
	struct xfs_da_args		*args = dac->da_args;
	struct xfs_da_state		**state = &dac->da_state;
	int				error;

	error = xfs_attr_node_hasname(args, state);
	if (error != -EEXIST)
		return error;
	error = 0;

	ASSERT((*state)->path.blk[(*state)->path.active - 1].bp != NULL);
	ASSERT((*state)->path.blk[(*state)->path.active - 1].magic ==
		XFS_ATTR_LEAF_MAGIC);

	if (args->rmtblkno > 0) {
		error = xfs_attr_leaf_mark_incomplete(args, *state);
		if (error)
			goto out;

		error = xfs_attr_rmtval_invalidate(args);
	}
out:
	if (error)
		xfs_da_state_free(*state);

	return error;
}

STATIC int
xfs_attr_node_removename(
	struct xfs_da_args	*args,
	struct xfs_da_state	*state)
{
	struct xfs_da_state_blk	*blk;
	int			retval;

	/*
	 * Remove the name and update the hashvals in the tree.
	 */
	blk = &state->path.blk[state->path.active-1];
	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
	retval = xfs_attr3_leaf_remove(blk->bp, args);
	xfs_da3_fixhashpath(state, &state->path);

	return retval;
}

/*
 * Remove the attribute specified in @args.
 *
 * This will involve walking down the Btree, and may involve joining
 * leaf nodes and even joining intermediate nodes up to and including
 * the root node (a special case of an intermediate node).
 *
 * This routine is meant to function as either an in-line or delayed operation,
 * and may return -EAGAIN when the transaction needs to be rolled.  Calling
 * functions will need to handle this, and call the function until a
 * successful error code is returned.
 */
int
xfs_attr_remove_iter(
	struct xfs_delattr_context	*dac)
{
	struct xfs_da_args		*args = dac->da_args;
	struct xfs_da_state		*state = dac->da_state;
	int				retval, error = 0;
	struct xfs_inode		*dp = args->dp;

	trace_xfs_attr_node_removename(args);

	switch (dac->dela_state) {
	case XFS_DAS_UNINIT:
		if (!xfs_inode_hasattr(dp))
			return -ENOATTR;

		/*
		 * Shortform or leaf formats don't require transaction rolls and
		 * thus state transitions. Call the right helper and return.
		 */
		if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL)
			return xfs_attr_sf_removename(args);

		if (xfs_attr_is_leaf(dp))
			return xfs_attr_leaf_removename(args);

		/*
		 * Node format may require transaction rolls. Set up the
		 * state context and fall into the state machine.
		 */
		if (!dac->da_state) {
			error = xfs_attr_node_removename_setup(dac);
			if (error)
				return error;
			state = dac->da_state;
		}

		fallthrough;
	case XFS_DAS_RMTBLK:
		dac->dela_state = XFS_DAS_RMTBLK;

		/*
		 * If there is an out-of-line value, de-allocate the blocks.
		 * This is done before we remove the attribute so that we don't
		 * overflow the maximum size of a transaction and/or hit a
		 * deadlock.
		 */
		if (args->rmtblkno > 0) {
			/*
			 * May return -EAGAIN. Roll and repeat until all remote
			 * blocks are removed.
			 */
			error = __xfs_attr_rmtval_remove(dac);
			if (error == -EAGAIN)
				return error;
			else if (error)
				goto out;

			/*
			 * Refill the state structure with buffers (the prior
			 * calls released our buffers) and close out this
			 * transaction before proceeding.
			 */
			ASSERT(args->rmtblkno == 0);
			error = xfs_attr_refillstate(state);
			if (error)
				goto out;
			dac->dela_state = XFS_DAS_RM_NAME;
			dac->flags |= XFS_DAC_DEFER_FINISH;
			return -EAGAIN;
		}

		fallthrough;
	case XFS_DAS_RM_NAME:
		/*
		 * If we came here fresh from a transaction roll, reattach all
		 * the buffers to the current transaction.
		 */
		if (dac->dela_state == XFS_DAS_RM_NAME) {
			error = xfs_attr_refillstate(state);
			if (error)
				goto out;
		}

		retval = xfs_attr_node_removename(args, state);

		/*
		 * Check to see if the tree needs to be collapsed. If so, roll
		 * the transacton and fall into the shrink state.
		 */
		if (retval && (state->path.active > 1)) {
			error = xfs_da3_join(state);
			if (error)
				goto out;

			dac->flags |= XFS_DAC_DEFER_FINISH;
			dac->dela_state = XFS_DAS_RM_SHRINK;
			return -EAGAIN;
		}

		fallthrough;
	case XFS_DAS_RM_SHRINK:
		/*
		 * If the result is small enough, push it all into the inode.
		 * This is our final state so it's safe to return a dirty
		 * transaction.
		 */
		if (xfs_attr_is_leaf(dp))
			error = xfs_attr_node_shrink(args, state);
		ASSERT(error != -EAGAIN);
		break;
	default:
		ASSERT(0);
		error = -EINVAL;
		goto out;
	}
out:
	if (state)
		xfs_da_state_free(state);
	return error;
}

/*
 * Fill in the disk block numbers in the state structure for the buffers
 * that are attached to the state structure.
 * This is done so that we can quickly reattach ourselves to those buffers
 * after some set of transaction commits have released these buffers.
 */
STATIC int
xfs_attr_fillstate(xfs_da_state_t *state)
{
	xfs_da_state_path_t *path;
	xfs_da_state_blk_t *blk;
	int level;

	trace_xfs_attr_fillstate(state->args);

	/*
	 * Roll down the "path" in the state structure, storing the on-disk
	 * block number for those buffers in the "path".
	 */
	path = &state->path;
	ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
	for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
		if (blk->bp) {
			blk->disk_blkno = XFS_BUF_ADDR(blk->bp);
			blk->bp = NULL;
		} else {
			blk->disk_blkno = 0;
		}
	}

	/*
	 * Roll down the "altpath" in the state structure, storing the on-disk
	 * block number for those buffers in the "altpath".
	 */
	path = &state->altpath;
	ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
	for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
		if (blk->bp) {
			blk->disk_blkno = XFS_BUF_ADDR(blk->bp);
			blk->bp = NULL;
		} else {
			blk->disk_blkno = 0;
		}
	}

	return 0;
}

/*
 * Reattach the buffers to the state structure based on the disk block
 * numbers stored in the state structure.
 * This is done after some set of transaction commits have released those
 * buffers from our grip.
 */
STATIC int
xfs_attr_refillstate(xfs_da_state_t *state)
{
	xfs_da_state_path_t *path;
	xfs_da_state_blk_t *blk;
	int level, error;

	trace_xfs_attr_refillstate(state->args);

	/*
	 * Roll down the "path" in the state structure, storing the on-disk
	 * block number for those buffers in the "path".
	 */
	path = &state->path;
	ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
	for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
		if (blk->disk_blkno) {
			error = xfs_da3_node_read_mapped(state->args->trans,
					state->args->dp, blk->disk_blkno,
					&blk->bp, XFS_ATTR_FORK);
			if (error)
				return error;
		} else {
			blk->bp = NULL;
		}
	}

	/*
	 * Roll down the "altpath" in the state structure, storing the on-disk
	 * block number for those buffers in the "altpath".
	 */
	path = &state->altpath;
	ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
	for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
		if (blk->disk_blkno) {
			error = xfs_da3_node_read_mapped(state->args->trans,
					state->args->dp, blk->disk_blkno,
					&blk->bp, XFS_ATTR_FORK);
			if (error)
				return error;
		} else {
			blk->bp = NULL;
		}
	}

	return 0;
}

/*
 * Retrieve the attribute data from a node attribute list.
 *
 * This routine gets called for any attribute fork that has more than one
 * block, ie: both true Btree attr lists and for single-leaf-blocks with
 * "remote" values taking up more blocks.
 *
 * Returns 0 on successful retrieval, otherwise an error.
 */
STATIC int
xfs_attr_node_get(
	struct xfs_da_args	*args)
{
	struct xfs_da_state	*state;
	struct xfs_da_state_blk	*blk;
	int			i;
	int			error;

	trace_xfs_attr_node_get(args);

	/*
	 * Search to see if name exists, and get back a pointer to it.
	 */
	error = xfs_attr_node_hasname(args, &state);
	if (error != -EEXIST)
		goto out_release;

	/*
	 * Get the value, local or "remote"
	 */
	blk = &state->path.blk[state->path.active - 1];
	error = xfs_attr3_leaf_getvalue(blk->bp, args);

	/*
	 * If not in a transaction, we have to release all the buffers.
	 */
out_release:
	for (i = 0; state != NULL && i < state->path.active; i++) {
		xfs_trans_brelse(args->trans, state->path.blk[i].bp);
		state->path.blk[i].bp = NULL;
	}

	if (state)
		xfs_da_state_free(state);
	return error;
}

/* Returns true if the attribute entry name is valid. */
bool
xfs_attr_namecheck(
	const void	*name,
	size_t		length)
{
	/*
	 * MAXNAMELEN includes the trailing null, but (name/length) leave it
	 * out, so use >= for the length check.
	 */
	if (length >= MAXNAMELEN)
		return false;

	/* There shouldn't be any nulls here */
	return !memchr(name, 0, length);
}
