/*
 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software Foundation,
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <linux/capability.h>

#include "xfs.h"
#include "xfs_fs.h"
#include "xfs_types.h"
#include "xfs_bit.h"
#include "xfs_log.h"
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_alloc.h"
#include "xfs_btree.h"
#include "xfs_inode_item.h"
#include "xfs_bmap.h"
#include "xfs_attr.h"
#include "xfs_attr_leaf.h"
#include "xfs_error.h"
#include "xfs_quota.h"
#include "xfs_trans_space.h"
#include "xfs_acl.h"
#include "xfs_rw.h"
#include "xfs_vnodeops.h"

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

#define ATTR_SYSCOUNT	2
static struct attrnames posix_acl_access;
static struct attrnames posix_acl_default;
static struct attrnames *attr_system_names[ATTR_SYSCOUNT];

/*========================================================================
 * 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_addname(xfs_da_args_t *args);
STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
STATIC int xfs_attr_leaf_list(xfs_attr_list_context_t *context);

/*
 * Internal routines when attribute list is more than one block.
 */
STATIC int xfs_attr_node_get(xfs_da_args_t *args);
STATIC int xfs_attr_node_addname(xfs_da_args_t *args);
STATIC int xfs_attr_node_removename(xfs_da_args_t *args);
STATIC int xfs_attr_node_list(xfs_attr_list_context_t *context);
STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
STATIC int xfs_attr_refillstate(xfs_da_state_t *state);

/*
 * Routines to manipulate out-of-line attribute values.
 */
STATIC int xfs_attr_rmtval_set(xfs_da_args_t *args);
STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args);

#define ATTR_RMTVALUE_MAPSIZE	1	/* # of map entries at once */

#if defined(XFS_ATTR_TRACE)
ktrace_t *xfs_attr_trace_buf;
#endif


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

int
xfs_attr_fetch(xfs_inode_t *ip, const char *name, int namelen,
	       char *value, int *valuelenp, int flags, struct cred *cred)
{
	xfs_da_args_t   args;
	int             error;

	if ((XFS_IFORK_Q(ip) == 0) ||
	    (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
	     ip->i_d.di_anextents == 0))
		return(ENOATTR);

	/*
	 * Fill in the arg structure for this request.
	 */
	memset((char *)&args, 0, sizeof(args));
	args.name = name;
	args.namelen = namelen;
	args.value = value;
	args.valuelen = *valuelenp;
	args.flags = flags;
	args.hashval = xfs_da_hashname(args.name, args.namelen);
	args.dp = ip;
	args.whichfork = XFS_ATTR_FORK;

	/*
	 * Decide on what work routines to call based on the inode size.
	 */
	if (XFS_IFORK_Q(ip) == 0 ||
	    (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
	     ip->i_d.di_anextents == 0)) {
		error = XFS_ERROR(ENOATTR);
	} else if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
		error = xfs_attr_shortform_getvalue(&args);
	} else if (xfs_bmap_one_block(ip, XFS_ATTR_FORK)) {
		error = xfs_attr_leaf_get(&args);
	} else {
		error = xfs_attr_node_get(&args);
	}

	/*
	 * Return the number of bytes in the value to the caller.
	 */
	*valuelenp = args.valuelen;

	if (error == EEXIST)
		error = 0;
	return(error);
}

int
xfs_attr_get(
	xfs_inode_t	*ip,
	const char	*name,
	char		*value,
	int		*valuelenp,
	int		flags,
	cred_t		*cred)
{
	int		error, namelen;

	XFS_STATS_INC(xs_attr_get);

	if (!name)
		return(EINVAL);
	namelen = strlen(name);
	if (namelen >= MAXNAMELEN)
		return(EFAULT);		/* match IRIX behaviour */

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

	xfs_ilock(ip, XFS_ILOCK_SHARED);
	error = xfs_attr_fetch(ip, name, namelen, value, valuelenp, flags, cred);
	xfs_iunlock(ip, XFS_ILOCK_SHARED);
	return(error);
}

int
xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen,
		 char *value, int valuelen, int flags)
{
	xfs_da_args_t	args;
	xfs_fsblock_t	firstblock;
	xfs_bmap_free_t flist;
	int		error, err2, committed;
	int		local, size;
	uint		nblks;
	xfs_mount_t	*mp = dp->i_mount;
	int             rsvd = (flags & ATTR_ROOT) != 0;

	/*
	 * Attach the dquots to the inode.
	 */
	if ((error = XFS_QM_DQATTACH(mp, dp, 0)))
		return (error);

	/*
	 * 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(xfs_attr_sf_hdr_t) +
			      XFS_ATTR_SF_ENTSIZE_BYNAME(namelen, valuelen);

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

	/*
	 * Fill in the arg structure for this request.
	 */
	memset((char *)&args, 0, sizeof(args));
	args.name = name;
	args.namelen = namelen;
	args.value = value;
	args.valuelen = valuelen;
	args.flags = flags;
	args.hashval = xfs_da_hashname(args.name, args.namelen);
	args.dp = dp;
	args.firstblock = &firstblock;
	args.flist = &flist;
	args.whichfork = XFS_ATTR_FORK;
	args.addname = 1;
	args.oknoent = 1;

	/*
	 * Determine space new attribute will use, and if it would be
	 * "local" or "remote" (note: local != inline).
	 */
	size = xfs_attr_leaf_newentsize(namelen, valuelen,
					mp->m_sb.sb_blocksize, &local);

	nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
	if (local) {
		if (size > (mp->m_sb.sb_blocksize >> 1)) {
			/* Double split possible */
			nblks <<= 1;
		}
	} else {
		uint	dblocks = XFS_B_TO_FSB(mp, valuelen);
		/* Out of line attribute, cannot double split, but make
		 * room for the attribute value itself.
		 */
		nblks += dblocks;
		nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
	}

	/* Size is now blocks for attribute data */
	args.total = nblks;

	/*
	 * Start our first transaction of the day.
	 *
	 * All future transactions during this code must be "chained" off
	 * this one via the trans_dup() call.  All transactions will contain
	 * the inode, and the inode will always be marked with trans_ihold().
	 * Since the inode will be locked in all transactions, we must log
	 * the inode in every transaction to let it float upward through
	 * the log.
	 */
	args.trans = xfs_trans_alloc(mp, XFS_TRANS_ATTR_SET);

	/*
	 * Root fork attributes can use reserved data blocks for this
	 * operation if necessary
	 */

	if (rsvd)
		args.trans->t_flags |= XFS_TRANS_RESERVE;

	if ((error = xfs_trans_reserve(args.trans, (uint) nblks,
				      XFS_ATTRSET_LOG_RES(mp, nblks),
				      0, XFS_TRANS_PERM_LOG_RES,
				      XFS_ATTRSET_LOG_COUNT))) {
		xfs_trans_cancel(args.trans, 0);
		return(error);
	}
	xfs_ilock(dp, XFS_ILOCK_EXCL);

	error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, args.trans, dp, nblks, 0,
			 rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
				XFS_QMOPT_RES_REGBLKS);
	if (error) {
		xfs_iunlock(dp, XFS_ILOCK_EXCL);
		xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES);
		return (error);
	}

	xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL);
	xfs_trans_ihold(args.trans, dp);

	/*
	 * If the attribute list is non-existent or a shortform list,
	 * upgrade it to a single-leaf-block attribute list.
	 */
	if ((dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) ||
	    ((dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) &&
	     (dp->i_d.di_anextents == 0))) {

		/*
		 * Build initial attribute list (if required).
		 */
		if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS)
			xfs_attr_shortform_create(&args);

		/*
		 * Try to add the attr to the attribute list in
		 * the inode.
		 */
		error = xfs_attr_shortform_addname(&args);
		if (error != ENOSPC) {
			/*
			 * Commit the shortform mods, and we're done.
			 * NOTE: this is also the error path (EEXIST, etc).
			 */
			ASSERT(args.trans != NULL);

			/*
			 * 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);
			}
			err2 = xfs_trans_commit(args.trans,
						 XFS_TRANS_RELEASE_LOG_RES);
			xfs_iunlock(dp, XFS_ILOCK_EXCL);

			/*
			 * Hit the inode change time.
			 */
			if (!error && (flags & ATTR_KERNOTIME) == 0) {
				xfs_ichgtime(dp, XFS_ICHGTIME_CHG);
			}
			return(error == 0 ? err2 : error);
		}

		/*
		 * It won't fit in the shortform, transform to a leaf block.
		 * GROT: another possible req'mt for a double-split btree op.
		 */
		XFS_BMAP_INIT(args.flist, args.firstblock);
		error = xfs_attr_shortform_to_leaf(&args);
		if (!error) {
			error = xfs_bmap_finish(&args.trans, args.flist,
						&committed);
		}
		if (error) {
			ASSERT(committed);
			args.trans = NULL;
			xfs_bmap_cancel(&flist);
			goto out;
		}

		/*
		 * bmap_finish() may have committed the last trans and started
		 * a new one.  We need the inode to be in all transactions.
		 */
		if (committed) {
			xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL);
			xfs_trans_ihold(args.trans, dp);
		}

		/*
		 * Commit the leaf transformation.  We'll need another (linked)
		 * transaction to add the new attribute to the leaf.
		 */
		if ((error = xfs_attr_rolltrans(&args.trans, dp)))
			goto out;

	}

	if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
		error = xfs_attr_leaf_addname(&args);
	} else {
		error = xfs_attr_node_addname(&args);
	}
	if (error) {
		goto out;
	}

	/*
	 * 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);
	}

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

	/*
	 * Hit the inode change time.
	 */
	if (!error && (flags & ATTR_KERNOTIME) == 0) {
		xfs_ichgtime(dp, XFS_ICHGTIME_CHG);
	}

	return(error);

out:
	if (args.trans)
		xfs_trans_cancel(args.trans,
			XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
	xfs_iunlock(dp, XFS_ILOCK_EXCL);
	return(error);
}

int
xfs_attr_set(
	xfs_inode_t	*dp,
	const char	*name,
	char		*value,
	int		valuelen,
	int		flags)
{
	int             namelen;

	namelen = strlen(name);
	if (namelen >= MAXNAMELEN)
		return EFAULT;		/* match IRIX behaviour */

	XFS_STATS_INC(xs_attr_set);

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

	return xfs_attr_set_int(dp, name, namelen, value, valuelen, flags);
}

/*
 * Generic handler routine to remove a name from an attribute list.
 * Transitions attribute list from Btree to shortform as necessary.
 */
int
xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags)
{
	xfs_da_args_t	args;
	xfs_fsblock_t	firstblock;
	xfs_bmap_free_t	flist;
	int		error;
	xfs_mount_t	*mp = dp->i_mount;

	/*
	 * Fill in the arg structure for this request.
	 */
	memset((char *)&args, 0, sizeof(args));
	args.name = name;
	args.namelen = namelen;
	args.flags = flags;
	args.hashval = xfs_da_hashname(args.name, args.namelen);
	args.dp = dp;
	args.firstblock = &firstblock;
	args.flist = &flist;
	args.total = 0;
	args.whichfork = XFS_ATTR_FORK;

	/*
	 * Attach the dquots to the inode.
	 */
	if ((error = XFS_QM_DQATTACH(mp, dp, 0)))
		return (error);

	/*
	 * Start our first transaction of the day.
	 *
	 * All future transactions during this code must be "chained" off
	 * this one via the trans_dup() call.  All transactions will contain
	 * the inode, and the inode will always be marked with trans_ihold().
	 * Since the inode will be locked in all transactions, we must log
	 * the inode in every transaction to let it float upward through
	 * the log.
	 */
	args.trans = xfs_trans_alloc(mp, XFS_TRANS_ATTR_RM);

	/*
	 * Root fork attributes can use reserved data blocks for this
	 * operation if necessary
	 */

	if (flags & ATTR_ROOT)
		args.trans->t_flags |= XFS_TRANS_RESERVE;

	if ((error = xfs_trans_reserve(args.trans,
				      XFS_ATTRRM_SPACE_RES(mp),
				      XFS_ATTRRM_LOG_RES(mp),
				      0, XFS_TRANS_PERM_LOG_RES,
				      XFS_ATTRRM_LOG_COUNT))) {
		xfs_trans_cancel(args.trans, 0);
		return(error);
	}

	xfs_ilock(dp, XFS_ILOCK_EXCL);
	/*
	 * No need to make quota reservations here. We expect to release some
	 * blocks not allocate in the common case.
	 */
	xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL);
	xfs_trans_ihold(args.trans, dp);

	/*
	 * Decide on what work routines to call based on the inode size.
	 */
	if (XFS_IFORK_Q(dp) == 0 ||
	    (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
	     dp->i_d.di_anextents == 0)) {
		error = XFS_ERROR(ENOATTR);
		goto out;
	}
	if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
		ASSERT(dp->i_afp->if_flags & XFS_IFINLINE);
		error = xfs_attr_shortform_remove(&args);
		if (error) {
			goto out;
		}
	} else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
		error = xfs_attr_leaf_removename(&args);
	} else {
		error = xfs_attr_node_removename(&args);
	}
	if (error) {
		goto out;
	}

	/*
	 * 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);
	}

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

	/*
	 * Hit the inode change time.
	 */
	if (!error && (flags & ATTR_KERNOTIME) == 0) {
		xfs_ichgtime(dp, XFS_ICHGTIME_CHG);
	}

	return(error);

out:
	if (args.trans)
		xfs_trans_cancel(args.trans,
			XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
	xfs_iunlock(dp, XFS_ILOCK_EXCL);
	return(error);
}

int
xfs_attr_remove(
	xfs_inode_t	*dp,
	const char	*name,
	int		flags)
{
	int		namelen;

	namelen = strlen(name);
	if (namelen >= MAXNAMELEN)
		return EFAULT;		/* match IRIX behaviour */

	XFS_STATS_INC(xs_attr_remove);

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

	xfs_ilock(dp, XFS_ILOCK_SHARED);
	if (XFS_IFORK_Q(dp) == 0 ||
		   (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
		    dp->i_d.di_anextents == 0)) {
		xfs_iunlock(dp, XFS_ILOCK_SHARED);
		return(XFS_ERROR(ENOATTR));
	}
	xfs_iunlock(dp, XFS_ILOCK_SHARED);

	return xfs_attr_remove_int(dp, name, namelen, flags);
}

int								/* error */
xfs_attr_list_int(xfs_attr_list_context_t *context)
{
	int error;
	xfs_inode_t *dp = context->dp;

	/*
	 * Decide on what work routines to call based on the inode size.
	 */
	if (XFS_IFORK_Q(dp) == 0 ||
	    (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
	     dp->i_d.di_anextents == 0)) {
		error = 0;
	} else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
		error = xfs_attr_shortform_list(context);
	} else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
		error = xfs_attr_leaf_list(context);
	} else {
		error = xfs_attr_node_list(context);
	}
	return error;
}

#define	ATTR_ENTBASESIZE		/* minimum bytes used by an attr */ \
	(((struct attrlist_ent *) 0)->a_name - (char *) 0)
#define	ATTR_ENTSIZE(namelen)		/* actual bytes used by an attr */ \
	((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(u_int32_t)-1) \
	 & ~(sizeof(u_int32_t)-1))

/*
 * Format an attribute and copy it out to the user's buffer.
 * Take care to check values and protect against them changing later,
 * we may be reading them directly out of a user buffer.
 */
/*ARGSUSED*/
STATIC int
xfs_attr_put_listent(xfs_attr_list_context_t *context, attrnames_t *namesp,
		     char *name, int namelen,
		     int valuelen, char *value)
{
	attrlist_ent_t *aep;
	int arraytop;

	ASSERT(!(context->flags & ATTR_KERNOVAL));
	ASSERT(context->count >= 0);
	ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
	ASSERT(context->firstu >= sizeof(*context->alist));
	ASSERT(context->firstu <= context->bufsize);

	arraytop = sizeof(*context->alist) +
			context->count * sizeof(context->alist->al_offset[0]);
	context->firstu -= ATTR_ENTSIZE(namelen);
	if (context->firstu < arraytop) {
		xfs_attr_trace_l_c("buffer full", context);
		context->alist->al_more = 1;
		context->seen_enough = 1;
		return 1;
	}

	aep = (attrlist_ent_t *)&(((char *)context->alist)[ context->firstu ]);
	aep->a_valuelen = valuelen;
	memcpy(aep->a_name, name, namelen);
	aep->a_name[ namelen ] = 0;
	context->alist->al_offset[ context->count++ ] = context->firstu;
	context->alist->al_count = context->count;
	xfs_attr_trace_l_c("add", context);
	return 0;
}

STATIC int
xfs_attr_kern_list(xfs_attr_list_context_t *context, attrnames_t *namesp,
		     char *name, int namelen,
		     int valuelen, char *value)
{
	char *offset;
	int arraytop;

	ASSERT(context->count >= 0);

	arraytop = context->count + namesp->attr_namelen + namelen + 1;
	if (arraytop > context->firstu) {
		context->count = -1;	/* insufficient space */
		return 1;
	}
	offset = (char *)context->alist + context->count;
	strncpy(offset, namesp->attr_name, namesp->attr_namelen);
	offset += namesp->attr_namelen;
	strncpy(offset, name, namelen);			/* real name */
	offset += namelen;
	*offset = '\0';
	context->count += namesp->attr_namelen + namelen + 1;
	return 0;
}

/*ARGSUSED*/
STATIC int
xfs_attr_kern_list_sizes(xfs_attr_list_context_t *context, attrnames_t *namesp,
		     char *name, int namelen,
		     int valuelen, char *value)
{
	context->count += namesp->attr_namelen + namelen + 1;
	return 0;
}

/*
 * Generate a list of extended attribute names and optionally
 * also value lengths.  Positive return value follows the XFS
 * convention of being an error, zero or negative return code
 * is the length of the buffer returned (negated), indicating
 * success.
 */
int
xfs_attr_list(
	xfs_inode_t	*dp,
	char		*buffer,
	int		bufsize,
	int		flags,
	attrlist_cursor_kern_t *cursor)
{
	xfs_attr_list_context_t context;
	int error;

	XFS_STATS_INC(xs_attr_list);

	/*
	 * Validate the cursor.
	 */
	if (cursor->pad1 || cursor->pad2)
		return(XFS_ERROR(EINVAL));
	if ((cursor->initted == 0) &&
	    (cursor->hashval || cursor->blkno || cursor->offset))
		return XFS_ERROR(EINVAL);

	/*
	 * Check for a properly aligned buffer.
	 */
	if (((long)buffer) & (sizeof(int)-1))
		return XFS_ERROR(EFAULT);
	if (flags & ATTR_KERNOVAL)
		bufsize = 0;

	/*
	 * Initialize the output buffer.
	 */
	context.dp = dp;
	context.cursor = cursor;
	context.count = 0;
	context.dupcnt = 0;
	context.resynch = 1;
	context.flags = flags;
	context.seen_enough = 0;
	context.alist = (attrlist_t *)buffer;
	context.put_value = 0;

	if (flags & ATTR_KERNAMELS) {
		context.bufsize = bufsize;
		context.firstu = context.bufsize;
		if (flags & ATTR_KERNOVAL)
			context.put_listent = xfs_attr_kern_list_sizes;
		else
			context.put_listent = xfs_attr_kern_list;
	} else {
		context.bufsize = (bufsize & ~(sizeof(int)-1));  /* align */
		context.firstu = context.bufsize;
		context.alist->al_count = 0;
		context.alist->al_more = 0;
		context.alist->al_offset[0] = context.bufsize;
		context.put_listent = xfs_attr_put_listent;
	}

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

	xfs_ilock(dp, XFS_ILOCK_SHARED);
	xfs_attr_trace_l_c("syscall start", &context);

	error = xfs_attr_list_int(&context);

	xfs_iunlock(dp, XFS_ILOCK_SHARED);
	xfs_attr_trace_l_c("syscall end", &context);

	if (context.flags & (ATTR_KERNOVAL|ATTR_KERNAMELS)) {
		/* must return negated buffer size or the error */
		if (context.count < 0)
			error = XFS_ERROR(ERANGE);
		else
			error = -context.count;
	} else
		ASSERT(error >= 0);

	return error;
}

int								/* error */
xfs_attr_inactive(xfs_inode_t *dp)
{
	xfs_trans_t *trans;
	xfs_mount_t *mp;
	int error;

	mp = dp->i_mount;
	ASSERT(! XFS_NOT_DQATTACHED(mp, dp));

	xfs_ilock(dp, XFS_ILOCK_SHARED);
	if ((XFS_IFORK_Q(dp) == 0) ||
	    (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) ||
	    (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
	     dp->i_d.di_anextents == 0)) {
		xfs_iunlock(dp, XFS_ILOCK_SHARED);
		return(0);
	}
	xfs_iunlock(dp, XFS_ILOCK_SHARED);

	/*
	 * Start our first transaction of the day.
	 *
	 * All future transactions during this code must be "chained" off
	 * this one via the trans_dup() call.  All transactions will contain
	 * the inode, and the inode will always be marked with trans_ihold().
	 * Since the inode will be locked in all transactions, we must log
	 * the inode in every transaction to let it float upward through
	 * the log.
	 */
	trans = xfs_trans_alloc(mp, XFS_TRANS_ATTRINVAL);
	if ((error = xfs_trans_reserve(trans, 0, XFS_ATTRINVAL_LOG_RES(mp), 0,
				      XFS_TRANS_PERM_LOG_RES,
				      XFS_ATTRINVAL_LOG_COUNT))) {
		xfs_trans_cancel(trans, 0);
		return(error);
	}
	xfs_ilock(dp, XFS_ILOCK_EXCL);

	/*
	 * No need to make quota reservations here. We expect to release some
	 * blocks, not allocate, in the common case.
	 */
	xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL);
	xfs_trans_ihold(trans, dp);

	/*
	 * Decide on what work routines to call based on the inode size.
	 */
	if ((XFS_IFORK_Q(dp) == 0) ||
	    (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) ||
	    (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
	     dp->i_d.di_anextents == 0)) {
		error = 0;
		goto out;
	}
	error = xfs_attr_root_inactive(&trans, dp);
	if (error)
		goto out;
	/*
	 * signal synchronous inactive transactions unless this
	 * is a synchronous mount filesystem in which case we
	 * know that we're here because we've been called out of
	 * xfs_inactive which means that the last reference is gone
	 * and the unlink transaction has already hit the disk so
	 * async inactive transactions are safe.
	 */
	if ((error = xfs_itruncate_finish(&trans, dp, 0LL, XFS_ATTR_FORK,
				(!(mp->m_flags & XFS_MOUNT_WSYNC)
				 ? 1 : 0))))
		goto out;

	/*
	 * Commit the last in the sequence of transactions.
	 */
	xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE);
	error = xfs_trans_commit(trans, XFS_TRANS_RELEASE_LOG_RES);
	xfs_iunlock(dp, XFS_ILOCK_EXCL);

	return(error);

out:
	xfs_trans_cancel(trans, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
	xfs_iunlock(dp, XFS_ILOCK_EXCL);
	return(error);
}



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

/*
 * 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;

	retval = xfs_attr_shortform_lookup(args);
	if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) {
		return(retval);
	} else if (retval == EEXIST) {
		if (args->flags & ATTR_CREATE)
			return(retval);
		retval = xfs_attr_shortform_remove(args);
		ASSERT(retval == 0);
	}

	if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
	    args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
		return(XFS_ERROR(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(XFS_ERROR(ENOSPC));

	xfs_attr_shortform_add(args, forkoff);
	return(0);
}


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

/*
 * Add a name to 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_addname(xfs_da_args_t *args)
{
	xfs_inode_t *dp;
	xfs_dabuf_t *bp;
	int retval, error, committed, forkoff;

	/*
	 * Read the (only) block in the attribute list in.
	 */
	dp = args->dp;
	args->blkno = 0;
	error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp,
					     XFS_ATTR_FORK);
	if (error)
		return(error);
	ASSERT(bp != NULL);

	/*
	 * 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_lookup_int(bp, args);
	if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) {
		xfs_da_brelse(args->trans, bp);
		return(retval);
	} else if (retval == EEXIST) {
		if (args->flags & ATTR_CREATE) {	/* pure create op */
			xfs_da_brelse(args->trans, bp);
			return(retval);
		}
		args->rename = 1;			/* an atomic rename */
		args->blkno2 = args->blkno;		/* set 2nd entry info*/
		args->index2 = args->index;
		args->rmtblkno2 = args->rmtblkno;
		args->rmtblkcnt2 = args->rmtblkcnt;
	}

	/*
	 * Add the attribute to the leaf block, transitioning to a Btree
	 * if required.
	 */
	retval = xfs_attr_leaf_add(bp, args);
	xfs_da_buf_done(bp);
	if (retval == ENOSPC) {
		/*
		 * Promote the attribute list to the Btree format, then
		 * Commit that transaction so that the node_addname() call
		 * can manage its own transactions.
		 */
		XFS_BMAP_INIT(args->flist, args->firstblock);
		error = xfs_attr_leaf_to_node(args);
		if (!error) {
			error = xfs_bmap_finish(&args->trans, args->flist,
						&committed);
		}
		if (error) {
			ASSERT(committed);
			args->trans = NULL;
			xfs_bmap_cancel(args->flist);
			return(error);
		}

		/*
		 * bmap_finish() may have committed the last trans and started
		 * a new one.  We need the inode to be in all transactions.
		 */
		if (committed) {
			xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
			xfs_trans_ihold(args->trans, dp);
		}

		/*
		 * Commit the current trans (including the inode) and start
		 * a new one.
		 */
		if ((error = xfs_attr_rolltrans(&args->trans, dp)))
			return (error);

		/*
		 * Fob the whole rest of the problem off on the Btree code.
		 */
		error = xfs_attr_node_addname(args);
		return(error);
	}

	/*
	 * Commit the transaction that added the attr name so that
	 * later routines can manage their own transactions.
	 */
	if ((error = xfs_attr_rolltrans(&args->trans, dp)))
		return (error);

	/*
	 * 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.
	 */
	if (args->rmtblkno > 0) {
		error = xfs_attr_rmtval_set(args);
		if (error)
			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.
	 */
	if (args->rename) {
		/*
		 * In a separate transaction, set the incomplete flag on the
		 * "old" attr and clear the incomplete flag on the "new" attr.
		 */
		error = xfs_attr_leaf_flipflags(args);
		if (error)
			return(error);

		/*
		 * Dismantle the "old" attribute/value pair by removing
		 * a "remote" value (if it exists).
		 */
		args->index = args->index2;
		args->blkno = args->blkno2;
		args->rmtblkno = args->rmtblkno2;
		args->rmtblkcnt = args->rmtblkcnt2;
		if (args->rmtblkno) {
			error = xfs_attr_rmtval_remove(args);
			if (error)
				return(error);
		}

		/*
		 * Read in the block containing the "old" attr, then
		 * remove the "old" attr from that block (neat, huh!)
		 */
		error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1,
						     &bp, XFS_ATTR_FORK);
		if (error)
			return(error);
		ASSERT(bp != NULL);
		(void)xfs_attr_leaf_remove(bp, args);

		/*
		 * If the result is small enough, shrink it all into the inode.
		 */
		if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
			XFS_BMAP_INIT(args->flist, args->firstblock);
			error = xfs_attr_leaf_to_shortform(bp, args, forkoff);
			/* bp is gone due to xfs_da_shrink_inode */
			if (!error) {
				error = xfs_bmap_finish(&args->trans,
							args->flist,
							&committed);
			}
			if (error) {
				ASSERT(committed);
				args->trans = NULL;
				xfs_bmap_cancel(args->flist);
				return(error);
			}

			/*
			 * bmap_finish() may have committed the last trans
			 * and started a new one.  We need the inode to be
			 * in all transactions.
			 */
			if (committed) {
				xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
				xfs_trans_ihold(args->trans, dp);
			}
		} else
			xfs_da_buf_done(bp);

		/*
		 * Commit the remove and start the next trans in series.
		 */
		error = xfs_attr_rolltrans(&args->trans, dp);

	} else if (args->rmtblkno > 0) {
		/*
		 * Added a "remote" value, just clear the incomplete flag.
		 */
		error = xfs_attr_leaf_clearflag(args);
	}
	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(xfs_da_args_t *args)
{
	xfs_inode_t *dp;
	xfs_dabuf_t *bp;
	int error, committed, forkoff;

	/*
	 * Remove the attribute.
	 */
	dp = args->dp;
	args->blkno = 0;
	error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp,
					     XFS_ATTR_FORK);
	if (error) {
		return(error);
	}

	ASSERT(bp != NULL);
	error = xfs_attr_leaf_lookup_int(bp, args);
	if (error == ENOATTR) {
		xfs_da_brelse(args->trans, bp);
		return(error);
	}

	(void)xfs_attr_leaf_remove(bp, args);

	/*
	 * If the result is small enough, shrink it all into the inode.
	 */
	if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
		XFS_BMAP_INIT(args->flist, args->firstblock);
		error = xfs_attr_leaf_to_shortform(bp, args, forkoff);
		/* bp is gone due to xfs_da_shrink_inode */
		if (!error) {
			error = xfs_bmap_finish(&args->trans, args->flist,
						&committed);
		}
		if (error) {
			ASSERT(committed);
			args->trans = NULL;
			xfs_bmap_cancel(args->flist);
			return(error);
		}

		/*
		 * bmap_finish() may have committed the last trans and started
		 * a new one.  We need the inode to be in all transactions.
		 */
		if (committed) {
			xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
			xfs_trans_ihold(args->trans, dp);
		}
	} else
		xfs_da_buf_done(bp);
	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).
 */
STATIC int
xfs_attr_leaf_get(xfs_da_args_t *args)
{
	xfs_dabuf_t *bp;
	int error;

	args->blkno = 0;
	error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp,
					     XFS_ATTR_FORK);
	if (error)
		return(error);
	ASSERT(bp != NULL);

	error = xfs_attr_leaf_lookup_int(bp, args);
	if (error != EEXIST)  {
		xfs_da_brelse(args->trans, bp);
		return(error);
	}
	error = xfs_attr_leaf_getvalue(bp, args);
	xfs_da_brelse(args->trans, bp);
	if (!error && (args->rmtblkno > 0) && !(args->flags & ATTR_KERNOVAL)) {
		error = xfs_attr_rmtval_get(args);
	}
	return(error);
}

/*
 * Copy out attribute entries for attr_list(), for leaf attribute lists.
 */
STATIC int
xfs_attr_leaf_list(xfs_attr_list_context_t *context)
{
	xfs_attr_leafblock_t *leaf;
	int error;
	xfs_dabuf_t *bp;

	context->cursor->blkno = 0;
	error = xfs_da_read_buf(NULL, context->dp, 0, -1, &bp, XFS_ATTR_FORK);
	if (error)
		return XFS_ERROR(error);
	ASSERT(bp != NULL);
	leaf = bp->data;
	if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC)) {
		XFS_CORRUPTION_ERROR("xfs_attr_leaf_list", XFS_ERRLEVEL_LOW,
				     context->dp->i_mount, leaf);
		xfs_da_brelse(NULL, bp);
		return XFS_ERROR(EFSCORRUPTED);
	}

	error = xfs_attr_leaf_list_int(bp, context);
	xfs_da_brelse(NULL, bp);
	return XFS_ERROR(error);
}


/*========================================================================
 * External routines when attribute list size > XFS_LBSIZE(mp).
 *========================================================================*/

/*
 * 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.
 */
STATIC int
xfs_attr_node_addname(xfs_da_args_t *args)
{
	xfs_da_state_t *state;
	xfs_da_state_blk_t *blk;
	xfs_inode_t *dp;
	xfs_mount_t *mp;
	int committed, retval, error;

	/*
	 * Fill in bucket of arguments/results/context to carry around.
	 */
	dp = args->dp;
	mp = dp->i_mount;
restart:
	state = xfs_da_state_alloc();
	state->args = args;
	state->mp = mp;
	state->blocksize = state->mp->m_sb.sb_blocksize;
	state->node_ents = state->mp->m_attr_node_ents;

	/*
	 * Search to see if name already exists, and get back a pointer
	 * to where it should go.
	 */
	error = xfs_da_node_lookup_int(state, &retval);
	if (error)
		goto out;
	blk = &state->path.blk[ state->path.active-1 ];
	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
	if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) {
		goto out;
	} else if (retval == EEXIST) {
		if (args->flags & ATTR_CREATE)
			goto out;
		args->rename = 1;			/* atomic rename op */
		args->blkno2 = args->blkno;		/* set 2nd entry info*/
		args->index2 = args->index;
		args->rmtblkno2 = args->rmtblkno;
		args->rmtblkcnt2 = args->rmtblkcnt;
		args->rmtblkno = 0;
		args->rmtblkcnt = 0;
	}

	retval = xfs_attr_leaf_add(blk->bp, state->args);
	if (retval == 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);
			XFS_BMAP_INIT(args->flist, args->firstblock);
			error = xfs_attr_leaf_to_node(args);
			if (!error) {
				error = xfs_bmap_finish(&args->trans,
							args->flist,
							&committed);
			}
			if (error) {
				ASSERT(committed);
				args->trans = NULL;
				xfs_bmap_cancel(args->flist);
				goto out;
			}

			/*
			 * bmap_finish() may have committed the last trans
			 * and started a new one.  We need the inode to be
			 * in all transactions.
			 */
			if (committed) {
				xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
				xfs_trans_ihold(args->trans, dp);
			}

			/*
			 * Commit the node conversion and start the next
			 * trans in the chain.
			 */
			if ((error = xfs_attr_rolltrans(&args->trans, dp)))
				goto out;

			goto restart;
		}

		/*
		 * 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.
		 */
		XFS_BMAP_INIT(args->flist, args->firstblock);
		error = xfs_da_split(state);
		if (!error) {
			error = xfs_bmap_finish(&args->trans, args->flist,
						&committed);
		}
		if (error) {
			ASSERT(committed);
			args->trans = NULL;
			xfs_bmap_cancel(args->flist);
			goto out;
		}

		/*
		 * bmap_finish() may have committed the last trans and started
		 * a new one.  We need the inode to be in all transactions.
		 */
		if (committed) {
			xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
			xfs_trans_ihold(args->trans, dp);
		}
	} else {
		/*
		 * Addition succeeded, update Btree hashvals.
		 */
		xfs_da_fixhashpath(state, &state->path);
	}

	/*
	 * Kill the state structure, we're done with it and need to
	 * allow the buffers to come back later.
	 */
	xfs_da_state_free(state);
	state = NULL;

	/*
	 * Commit the leaf addition or btree split and start the next
	 * trans in the chain.
	 */
	if ((error = xfs_attr_rolltrans(&args->trans, dp)))
		goto out;

	/*
	 * 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.
	 */
	if (args->rmtblkno > 0) {
		error = xfs_attr_rmtval_set(args);
		if (error)
			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.
	 */
	if (args->rename) {
		/*
		 * In a separate transaction, set the incomplete flag on the
		 * "old" attr and clear the incomplete flag on the "new" attr.
		 */
		error = xfs_attr_leaf_flipflags(args);
		if (error)
			goto out;

		/*
		 * Dismantle the "old" attribute/value pair by removing
		 * a "remote" value (if it exists).
		 */
		args->index = args->index2;
		args->blkno = args->blkno2;
		args->rmtblkno = args->rmtblkno2;
		args->rmtblkcnt = args->rmtblkcnt2;
		if (args->rmtblkno) {
			error = xfs_attr_rmtval_remove(args);
			if (error)
				return(error);
		}

		/*
		 * 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->flags |= XFS_ATTR_INCOMPLETE;
		state = xfs_da_state_alloc();
		state->args = args;
		state->mp = mp;
		state->blocksize = state->mp->m_sb.sb_blocksize;
		state->node_ents = state->mp->m_attr_node_ents;
		state->inleaf = 0;
		error = xfs_da_node_lookup_int(state, &retval);
		if (error)
			goto out;

		/*
		 * 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);
		error = xfs_attr_leaf_remove(blk->bp, args);
		xfs_da_fixhashpath(state, &state->path);

		/*
		 * Check to see if the tree needs to be collapsed.
		 */
		if (retval && (state->path.active > 1)) {
			XFS_BMAP_INIT(args->flist, args->firstblock);
			error = xfs_da_join(state);
			if (!error) {
				error = xfs_bmap_finish(&args->trans,
							args->flist,
							&committed);
			}
			if (error) {
				ASSERT(committed);
				args->trans = NULL;
				xfs_bmap_cancel(args->flist);
				goto out;
			}

			/*
			 * bmap_finish() may have committed the last trans
			 * and started a new one.  We need the inode to be
			 * in all transactions.
			 */
			if (committed) {
				xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
				xfs_trans_ihold(args->trans, dp);
			}
		}

		/*
		 * Commit and start the next trans in the chain.
		 */
		if ((error = xfs_attr_rolltrans(&args->trans, dp)))
			goto out;

	} else if (args->rmtblkno > 0) {
		/*
		 * Added a "remote" value, just clear the incomplete flag.
		 */
		error = xfs_attr_leaf_clearflag(args);
		if (error)
			goto out;
	}
	retval = error = 0;

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

/*
 * Remove a name from a B-tree attribute list.
 *
 * 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).
 */
STATIC int
xfs_attr_node_removename(xfs_da_args_t *args)
{
	xfs_da_state_t *state;
	xfs_da_state_blk_t *blk;
	xfs_inode_t *dp;
	xfs_dabuf_t *bp;
	int retval, error, committed, forkoff;

	/*
	 * Tie a string around our finger to remind us where we are.
	 */
	dp = args->dp;
	state = xfs_da_state_alloc();
	state->args = args;
	state->mp = dp->i_mount;
	state->blocksize = state->mp->m_sb.sb_blocksize;
	state->node_ents = state->mp->m_attr_node_ents;

	/*
	 * Search to see if name exists, and get back a pointer to it.
	 */
	error = xfs_da_node_lookup_int(state, &retval);
	if (error || (retval != EEXIST)) {
		if (error == 0)
			error = retval;
		goto out;
	}

	/*
	 * 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.
	 */
	blk = &state->path.blk[ state->path.active-1 ];
	ASSERT(blk->bp != NULL);
	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
	if (args->rmtblkno > 0) {
		/*
		 * 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)
			goto out;

		/*
		 * Mark the attribute as INCOMPLETE, then bunmapi() the
		 * remote value.
		 */
		error = xfs_attr_leaf_setflag(args);
		if (error)
			goto out;
		error = xfs_attr_rmtval_remove(args);
		if (error)
			goto out;

		/*
		 * Refill the state structure with buffers, the prior calls
		 * released our buffers.
		 */
		error = xfs_attr_refillstate(state);
		if (error)
			goto out;
	}

	/*
	 * 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_attr_leaf_remove(blk->bp, args);
	xfs_da_fixhashpath(state, &state->path);

	/*
	 * Check to see if the tree needs to be collapsed.
	 */
	if (retval && (state->path.active > 1)) {
		XFS_BMAP_INIT(args->flist, args->firstblock);
		error = xfs_da_join(state);
		if (!error) {
			error = xfs_bmap_finish(&args->trans, args->flist,
						&committed);
		}
		if (error) {
			ASSERT(committed);
			args->trans = NULL;
			xfs_bmap_cancel(args->flist);
			goto out;
		}

		/*
		 * bmap_finish() may have committed the last trans and started
		 * a new one.  We need the inode to be in all transactions.
		 */
		if (committed) {
			xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
			xfs_trans_ihold(args->trans, dp);
		}

		/*
		 * Commit the Btree join operation and start a new trans.
		 */
		if ((error = xfs_attr_rolltrans(&args->trans, dp)))
			goto out;
	}

	/*
	 * If the result is small enough, push it all into the inode.
	 */
	if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
		/*
		 * Have to get rid of the copy of this dabuf in the state.
		 */
		ASSERT(state->path.active == 1);
		ASSERT(state->path.blk[0].bp);
		xfs_da_buf_done(state->path.blk[0].bp);
		state->path.blk[0].bp = NULL;

		error = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
						     XFS_ATTR_FORK);
		if (error)
			goto out;
		ASSERT(be16_to_cpu(((xfs_attr_leafblock_t *)
				      bp->data)->hdr.info.magic)
						       == XFS_ATTR_LEAF_MAGIC);

		if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
			XFS_BMAP_INIT(args->flist, args->firstblock);
			error = xfs_attr_leaf_to_shortform(bp, args, forkoff);
			/* bp is gone due to xfs_da_shrink_inode */
			if (!error) {
				error = xfs_bmap_finish(&args->trans,
							args->flist,
							&committed);
			}
			if (error) {
				ASSERT(committed);
				args->trans = NULL;
				xfs_bmap_cancel(args->flist);
				goto out;
			}

			/*
			 * bmap_finish() may have committed the last trans
			 * and started a new one.  We need the inode to be
			 * in all transactions.
			 */
			if (committed) {
				xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
				xfs_trans_ihold(args->trans, dp);
			}
		} else
			xfs_da_brelse(args->trans, bp);
	}
	error = 0;

out:
	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;

	/*
	 * 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_da_blkno(blk->bp);
			xfs_da_buf_done(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_da_blkno(blk->bp);
			xfs_da_buf_done(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;

	/*
	 * 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_da_read_buf(state->args->trans,
						state->args->dp,
						blk->blkno, 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_da_read_buf(state->args->trans,
						state->args->dp,
						blk->blkno, blk->disk_blkno,
						&blk->bp, XFS_ATTR_FORK);
			if (error)
				return(error);
		} else {
			blk->bp = NULL;
		}
	}

	return(0);
}

/*
 * Look up a filename in 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.
 */
STATIC int
xfs_attr_node_get(xfs_da_args_t *args)
{
	xfs_da_state_t *state;
	xfs_da_state_blk_t *blk;
	int error, retval;
	int i;

	state = xfs_da_state_alloc();
	state->args = args;
	state->mp = args->dp->i_mount;
	state->blocksize = state->mp->m_sb.sb_blocksize;
	state->node_ents = state->mp->m_attr_node_ents;

	/*
	 * Search to see if name exists, and get back a pointer to it.
	 */
	error = xfs_da_node_lookup_int(state, &retval);
	if (error) {
		retval = error;
	} else if (retval == EEXIST) {
		blk = &state->path.blk[ state->path.active-1 ];
		ASSERT(blk->bp != NULL);
		ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);

		/*
		 * Get the value, local or "remote"
		 */
		retval = xfs_attr_leaf_getvalue(blk->bp, args);
		if (!retval && (args->rmtblkno > 0)
		    && !(args->flags & ATTR_KERNOVAL)) {
			retval = xfs_attr_rmtval_get(args);
		}
	}

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

	xfs_da_state_free(state);
	return(retval);
}

STATIC int							/* error */
xfs_attr_node_list(xfs_attr_list_context_t *context)
{
	attrlist_cursor_kern_t *cursor;
	xfs_attr_leafblock_t *leaf;
	xfs_da_intnode_t *node;
	xfs_da_node_entry_t *btree;
	int error, i;
	xfs_dabuf_t *bp;

	cursor = context->cursor;
	cursor->initted = 1;

	/*
	 * Do all sorts of validation on the passed-in cursor structure.
	 * If anything is amiss, ignore the cursor and look up the hashval
	 * starting from the btree root.
	 */
	bp = NULL;
	if (cursor->blkno > 0) {
		error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1,
					      &bp, XFS_ATTR_FORK);
		if ((error != 0) && (error != EFSCORRUPTED))
			return(error);
		if (bp) {
			node = bp->data;
			switch (be16_to_cpu(node->hdr.info.magic)) {
			case XFS_DA_NODE_MAGIC:
				xfs_attr_trace_l_cn("wrong blk", context, node);
				xfs_da_brelse(NULL, bp);
				bp = NULL;
				break;
			case XFS_ATTR_LEAF_MAGIC:
				leaf = bp->data;
				if (cursor->hashval > be32_to_cpu(leaf->entries[
				    be16_to_cpu(leaf->hdr.count)-1].hashval)) {
					xfs_attr_trace_l_cl("wrong blk",
							   context, leaf);
					xfs_da_brelse(NULL, bp);
					bp = NULL;
				} else if (cursor->hashval <=
					     be32_to_cpu(leaf->entries[0].hashval)) {
					xfs_attr_trace_l_cl("maybe wrong blk",
							   context, leaf);
					xfs_da_brelse(NULL, bp);
					bp = NULL;
				}
				break;
			default:
				xfs_attr_trace_l_c("wrong blk - ??", context);
				xfs_da_brelse(NULL, bp);
				bp = NULL;
			}
		}
	}

	/*
	 * We did not find what we expected given the cursor's contents,
	 * so we start from the top and work down based on the hash value.
	 * Note that start of node block is same as start of leaf block.
	 */
	if (bp == NULL) {
		cursor->blkno = 0;
		for (;;) {
			error = xfs_da_read_buf(NULL, context->dp,
						      cursor->blkno, -1, &bp,
						      XFS_ATTR_FORK);
			if (error)
				return(error);
			if (unlikely(bp == NULL)) {
				XFS_ERROR_REPORT("xfs_attr_node_list(2)",
						 XFS_ERRLEVEL_LOW,
						 context->dp->i_mount);
				return(XFS_ERROR(EFSCORRUPTED));
			}
			node = bp->data;
			if (be16_to_cpu(node->hdr.info.magic)
							== XFS_ATTR_LEAF_MAGIC)
				break;
			if (unlikely(be16_to_cpu(node->hdr.info.magic)
							!= XFS_DA_NODE_MAGIC)) {
				XFS_CORRUPTION_ERROR("xfs_attr_node_list(3)",
						     XFS_ERRLEVEL_LOW,
						     context->dp->i_mount,
						     node);
				xfs_da_brelse(NULL, bp);
				return(XFS_ERROR(EFSCORRUPTED));
			}
			btree = node->btree;
			for (i = 0; i < be16_to_cpu(node->hdr.count);
								btree++, i++) {
				if (cursor->hashval
						<= be32_to_cpu(btree->hashval)) {
					cursor->blkno = be32_to_cpu(btree->before);
					xfs_attr_trace_l_cb("descending",
							    context, btree);
					break;
				}
			}
			if (i == be16_to_cpu(node->hdr.count)) {
				xfs_da_brelse(NULL, bp);
				return(0);
			}
			xfs_da_brelse(NULL, bp);
		}
	}
	ASSERT(bp != NULL);

	/*
	 * Roll upward through the blocks, processing each leaf block in
	 * order.  As long as there is space in the result buffer, keep
	 * adding the information.
	 */
	for (;;) {
		leaf = bp->data;
		if (unlikely(be16_to_cpu(leaf->hdr.info.magic)
						!= XFS_ATTR_LEAF_MAGIC)) {
			XFS_CORRUPTION_ERROR("xfs_attr_node_list(4)",
					     XFS_ERRLEVEL_LOW,
					     context->dp->i_mount, leaf);
			xfs_da_brelse(NULL, bp);
			return(XFS_ERROR(EFSCORRUPTED));
		}
		error = xfs_attr_leaf_list_int(bp, context);
		if (error) {
			xfs_da_brelse(NULL, bp);
			return error;
		}
		if (context->seen_enough || leaf->hdr.info.forw == 0)
			break;
		cursor->blkno = be32_to_cpu(leaf->hdr.info.forw);
		xfs_da_brelse(NULL, bp);
		error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1,
					      &bp, XFS_ATTR_FORK);
		if (error)
			return(error);
		if (unlikely((bp == NULL))) {
			XFS_ERROR_REPORT("xfs_attr_node_list(5)",
					 XFS_ERRLEVEL_LOW,
					 context->dp->i_mount);
			return(XFS_ERROR(EFSCORRUPTED));
		}
	}
	xfs_da_brelse(NULL, bp);
	return(0);
}


/*========================================================================
 * External routines for manipulating out-of-line attribute values.
 *========================================================================*/

/*
 * Read the value associated with an attribute from the out-of-line buffer
 * that we stored it in.
 */
int
xfs_attr_rmtval_get(xfs_da_args_t *args)
{
	xfs_bmbt_irec_t map[ATTR_RMTVALUE_MAPSIZE];
	xfs_mount_t *mp;
	xfs_daddr_t dblkno;
	xfs_caddr_t dst;
	xfs_buf_t *bp;
	int nmap, error, tmp, valuelen, blkcnt, i;
	xfs_dablk_t lblkno;

	ASSERT(!(args->flags & ATTR_KERNOVAL));

	mp = args->dp->i_mount;
	dst = args->value;
	valuelen = args->valuelen;
	lblkno = args->rmtblkno;
	while (valuelen > 0) {
		nmap = ATTR_RMTVALUE_MAPSIZE;
		error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno,
				  args->rmtblkcnt,
				  XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
				  NULL, 0, map, &nmap, NULL, NULL);
		if (error)
			return(error);
		ASSERT(nmap >= 1);

		for (i = 0; (i < nmap) && (valuelen > 0); i++) {
			ASSERT((map[i].br_startblock != DELAYSTARTBLOCK) &&
			       (map[i].br_startblock != HOLESTARTBLOCK));
			dblkno = XFS_FSB_TO_DADDR(mp, map[i].br_startblock);
			blkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
			error = xfs_read_buf(mp, mp->m_ddev_targp, dblkno,
					     blkcnt, XFS_BUF_LOCK, &bp);
			if (error)
				return(error);

			tmp = (valuelen < XFS_BUF_SIZE(bp))
				? valuelen : XFS_BUF_SIZE(bp);
			xfs_biomove(bp, 0, tmp, dst, XFS_B_READ);
			xfs_buf_relse(bp);
			dst += tmp;
			valuelen -= tmp;

			lblkno += map[i].br_blockcount;
		}
	}
	ASSERT(valuelen == 0);
	return(0);
}

/*
 * Write the value associated with an attribute into the out-of-line buffer
 * that we have defined for it.
 */
STATIC int
xfs_attr_rmtval_set(xfs_da_args_t *args)
{
	xfs_mount_t *mp;
	xfs_fileoff_t lfileoff;
	xfs_inode_t *dp;
	xfs_bmbt_irec_t map;
	xfs_daddr_t dblkno;
	xfs_caddr_t src;
	xfs_buf_t *bp;
	xfs_dablk_t lblkno;
	int blkcnt, valuelen, nmap, error, tmp, committed;

	dp = args->dp;
	mp = dp->i_mount;
	src = args->value;

	/*
	 * Find a "hole" in the attribute address space large enough for
	 * us to drop the new attribute's value into.
	 */
	blkcnt = XFS_B_TO_FSB(mp, args->valuelen);
	lfileoff = 0;
	error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff,
						   XFS_ATTR_FORK);
	if (error) {
		return(error);
	}
	args->rmtblkno = lblkno = (xfs_dablk_t)lfileoff;
	args->rmtblkcnt = blkcnt;

	/*
	 * Roll through the "value", allocating blocks on disk as required.
	 */
	while (blkcnt > 0) {
		/*
		 * Allocate a single extent, up to the size of the value.
		 */
		XFS_BMAP_INIT(args->flist, args->firstblock);
		nmap = 1;
		error = xfs_bmapi(args->trans, dp, (xfs_fileoff_t)lblkno,
				  blkcnt,
				  XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA |
							XFS_BMAPI_WRITE,
				  args->firstblock, args->total, &map, &nmap,
				  args->flist, NULL);
		if (!error) {
			error = xfs_bmap_finish(&args->trans, args->flist,
						&committed);
		}
		if (error) {
			ASSERT(committed);
			args->trans = NULL;
			xfs_bmap_cancel(args->flist);
			return(error);
		}

		/*
		 * bmap_finish() may have committed the last trans and started
		 * a new one.  We need the inode to be in all transactions.
		 */
		if (committed) {
			xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
			xfs_trans_ihold(args->trans, dp);
		}

		ASSERT(nmap == 1);
		ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
		       (map.br_startblock != HOLESTARTBLOCK));
		lblkno += map.br_blockcount;
		blkcnt -= map.br_blockcount;

		/*
		 * Start the next trans in the chain.
		 */
		if ((error = xfs_attr_rolltrans(&args->trans, dp)))
			return (error);
	}

	/*
	 * Roll through the "value", copying the attribute value to the
	 * already-allocated blocks.  Blocks are written synchronously
	 * so that we can know they are all on disk before we turn off
	 * the INCOMPLETE flag.
	 */
	lblkno = args->rmtblkno;
	valuelen = args->valuelen;
	while (valuelen > 0) {
		/*
		 * Try to remember where we decided to put the value.
		 */
		XFS_BMAP_INIT(args->flist, args->firstblock);
		nmap = 1;
		error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno,
				  args->rmtblkcnt,
				  XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
				  args->firstblock, 0, &map, &nmap,
				  NULL, NULL);
		if (error) {
			return(error);
		}
		ASSERT(nmap == 1);
		ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
		       (map.br_startblock != HOLESTARTBLOCK));

		dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock),
		blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);

		bp = xfs_buf_get_flags(mp->m_ddev_targp, dblkno,
							blkcnt, XFS_BUF_LOCK);
		ASSERT(bp);
		ASSERT(!XFS_BUF_GETERROR(bp));

		tmp = (valuelen < XFS_BUF_SIZE(bp)) ? valuelen :
							XFS_BUF_SIZE(bp);
		xfs_biomove(bp, 0, tmp, src, XFS_B_WRITE);
		if (tmp < XFS_BUF_SIZE(bp))
			xfs_biozero(bp, tmp, XFS_BUF_SIZE(bp) - tmp);
		if ((error = xfs_bwrite(mp, bp))) {/* GROT: NOTE: synchronous write */
			return (error);
		}
		src += tmp;
		valuelen -= tmp;

		lblkno += map.br_blockcount;
	}
	ASSERT(valuelen == 0);
	return(0);
}

/*
 * Remove the value associated with an attribute by deleting the
 * out-of-line buffer that it is stored on.
 */
STATIC int
xfs_attr_rmtval_remove(xfs_da_args_t *args)
{
	xfs_mount_t *mp;
	xfs_bmbt_irec_t map;
	xfs_buf_t *bp;
	xfs_daddr_t dblkno;
	xfs_dablk_t lblkno;
	int valuelen, blkcnt, nmap, error, done, committed;

	mp = args->dp->i_mount;

	/*
	 * Roll through the "value", invalidating the attribute value's
	 * blocks.
	 */
	lblkno = args->rmtblkno;
	valuelen = args->rmtblkcnt;
	while (valuelen > 0) {
		/*
		 * Try to remember where we decided to put the value.
		 */
		XFS_BMAP_INIT(args->flist, args->firstblock);
		nmap = 1;
		error = xfs_bmapi(NULL, args->dp, (xfs_fileoff_t)lblkno,
					args->rmtblkcnt,
					XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
					args->firstblock, 0, &map, &nmap,
					args->flist, NULL);
		if (error) {
			return(error);
		}
		ASSERT(nmap == 1);
		ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
		       (map.br_startblock != HOLESTARTBLOCK));

		dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock),
		blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);

		/*
		 * If the "remote" value is in the cache, remove it.
		 */
		bp = xfs_incore(mp->m_ddev_targp, dblkno, blkcnt,
				XFS_INCORE_TRYLOCK);
		if (bp) {
			XFS_BUF_STALE(bp);
			XFS_BUF_UNDELAYWRITE(bp);
			xfs_buf_relse(bp);
			bp = NULL;
		}

		valuelen -= map.br_blockcount;

		lblkno += map.br_blockcount;
	}

	/*
	 * Keep de-allocating extents until the remote-value region is gone.
	 */
	lblkno = args->rmtblkno;
	blkcnt = args->rmtblkcnt;
	done = 0;
	while (!done) {
		XFS_BMAP_INIT(args->flist, args->firstblock);
		error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt,
				    XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
				    1, args->firstblock, args->flist,
				    NULL, &done);
		if (!error) {
			error = xfs_bmap_finish(&args->trans, args->flist,
						&committed);
		}
		if (error) {
			ASSERT(committed);
			args->trans = NULL;
			xfs_bmap_cancel(args->flist);
			return(error);
		}

		/*
		 * bmap_finish() may have committed the last trans and started
		 * a new one.  We need the inode to be in all transactions.
		 */
		if (committed) {
			xfs_trans_ijoin(args->trans, args->dp, XFS_ILOCK_EXCL);
			xfs_trans_ihold(args->trans, args->dp);
		}

		/*
		 * Close out trans and start the next one in the chain.
		 */
		if ((error = xfs_attr_rolltrans(&args->trans, args->dp)))
			return (error);
	}
	return(0);
}

#if defined(XFS_ATTR_TRACE)
/*
 * Add a trace buffer entry for an attr_list context structure.
 */
void
xfs_attr_trace_l_c(char *where, struct xfs_attr_list_context *context)
{
	xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_C, where,
		(__psunsigned_t)context->dp,
		(__psunsigned_t)context->cursor->hashval,
		(__psunsigned_t)context->cursor->blkno,
		(__psunsigned_t)context->cursor->offset,
		(__psunsigned_t)context->alist,
		(__psunsigned_t)context->bufsize,
		(__psunsigned_t)context->count,
		(__psunsigned_t)context->firstu,
		(__psunsigned_t)
			((context->count > 0) &&
			!(context->flags & (ATTR_KERNAMELS|ATTR_KERNOVAL)))
				? (ATTR_ENTRY(context->alist,
					      context->count-1)->a_valuelen)
				: 0,
		(__psunsigned_t)context->dupcnt,
		(__psunsigned_t)context->flags,
		(__psunsigned_t)NULL,
		(__psunsigned_t)NULL,
		(__psunsigned_t)NULL);
}

/*
 * Add a trace buffer entry for a context structure and a Btree node.
 */
void
xfs_attr_trace_l_cn(char *where, struct xfs_attr_list_context *context,
			 struct xfs_da_intnode *node)
{
	xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_CN, where,
		(__psunsigned_t)context->dp,
		(__psunsigned_t)context->cursor->hashval,
		(__psunsigned_t)context->cursor->blkno,
		(__psunsigned_t)context->cursor->offset,
		(__psunsigned_t)context->alist,
		(__psunsigned_t)context->bufsize,
		(__psunsigned_t)context->count,
		(__psunsigned_t)context->firstu,
		(__psunsigned_t)
			((context->count > 0) &&
			!(context->flags & (ATTR_KERNAMELS|ATTR_KERNOVAL)))
				? (ATTR_ENTRY(context->alist,
					      context->count-1)->a_valuelen)
				: 0,
		(__psunsigned_t)context->dupcnt,
		(__psunsigned_t)context->flags,
		(__psunsigned_t)be16_to_cpu(node->hdr.count),
		(__psunsigned_t)be32_to_cpu(node->btree[0].hashval),
		(__psunsigned_t)be32_to_cpu(node->btree[
				    be16_to_cpu(node->hdr.count)-1].hashval));
}

/*
 * Add a trace buffer entry for a context structure and a Btree element.
 */
void
xfs_attr_trace_l_cb(char *where, struct xfs_attr_list_context *context,
			  struct xfs_da_node_entry *btree)
{
	xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_CB, where,
		(__psunsigned_t)context->dp,
		(__psunsigned_t)context->cursor->hashval,
		(__psunsigned_t)context->cursor->blkno,
		(__psunsigned_t)context->cursor->offset,
		(__psunsigned_t)context->alist,
		(__psunsigned_t)context->bufsize,
		(__psunsigned_t)context->count,
		(__psunsigned_t)context->firstu,
		(__psunsigned_t)
			((context->count > 0) &&
			!(context->flags & (ATTR_KERNAMELS|ATTR_KERNOVAL)))
				? (ATTR_ENTRY(context->alist,
					      context->count-1)->a_valuelen)
				: 0,
		(__psunsigned_t)context->dupcnt,
		(__psunsigned_t)context->flags,
		(__psunsigned_t)be32_to_cpu(btree->hashval),
		(__psunsigned_t)be32_to_cpu(btree->before),
		(__psunsigned_t)NULL);
}

/*
 * Add a trace buffer entry for a context structure and a leaf block.
 */
void
xfs_attr_trace_l_cl(char *where, struct xfs_attr_list_context *context,
			      struct xfs_attr_leafblock *leaf)
{
	xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_CL, where,
		(__psunsigned_t)context->dp,
		(__psunsigned_t)context->cursor->hashval,
		(__psunsigned_t)context->cursor->blkno,
		(__psunsigned_t)context->cursor->offset,
		(__psunsigned_t)context->alist,
		(__psunsigned_t)context->bufsize,
		(__psunsigned_t)context->count,
		(__psunsigned_t)context->firstu,
		(__psunsigned_t)
			((context->count > 0) &&
			!(context->flags & (ATTR_KERNAMELS|ATTR_KERNOVAL)))
				? (ATTR_ENTRY(context->alist,
					      context->count-1)->a_valuelen)
				: 0,
		(__psunsigned_t)context->dupcnt,
		(__psunsigned_t)context->flags,
		(__psunsigned_t)be16_to_cpu(leaf->hdr.count),
		(__psunsigned_t)be32_to_cpu(leaf->entries[0].hashval),
		(__psunsigned_t)be32_to_cpu(leaf->entries[
				be16_to_cpu(leaf->hdr.count)-1].hashval));
}

/*
 * Add a trace buffer entry for the arguments given to the routine,
 * generic form.
 */
void
xfs_attr_trace_enter(int type, char *where,
			 __psunsigned_t a2, __psunsigned_t a3,
			 __psunsigned_t a4, __psunsigned_t a5,
			 __psunsigned_t a6, __psunsigned_t a7,
			 __psunsigned_t a8, __psunsigned_t a9,
			 __psunsigned_t a10, __psunsigned_t a11,
			 __psunsigned_t a12, __psunsigned_t a13,
			 __psunsigned_t a14, __psunsigned_t a15)
{
	ASSERT(xfs_attr_trace_buf);
	ktrace_enter(xfs_attr_trace_buf, (void *)((__psunsigned_t)type),
					 (void *)where,
					 (void *)a2,  (void *)a3,  (void *)a4,
					 (void *)a5,  (void *)a6,  (void *)a7,
					 (void *)a8,  (void *)a9,  (void *)a10,
					 (void *)a11, (void *)a12, (void *)a13,
					 (void *)a14, (void *)a15);
}
#endif	/* XFS_ATTR_TRACE */


/*========================================================================
 * System (pseudo) namespace attribute interface routines.
 *========================================================================*/

STATIC int
posix_acl_access_set(
	bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
{
	return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS);
}

STATIC int
posix_acl_access_remove(
	bhv_vnode_t *vp, char *name, int xflags)
{
	return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS);
}

STATIC int
posix_acl_access_get(
	bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
{
	return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS);
}

STATIC int
posix_acl_access_exists(
	bhv_vnode_t *vp)
{
	return xfs_acl_vhasacl_access(vp);
}

STATIC int
posix_acl_default_set(
	bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
{
	return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT);
}

STATIC int
posix_acl_default_get(
	bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
{
	return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT);
}

STATIC int
posix_acl_default_remove(
	bhv_vnode_t *vp, char *name, int xflags)
{
	return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT);
}

STATIC int
posix_acl_default_exists(
	bhv_vnode_t *vp)
{
	return xfs_acl_vhasacl_default(vp);
}

static struct attrnames posix_acl_access = {
	.attr_name	= "posix_acl_access",
	.attr_namelen	= sizeof("posix_acl_access") - 1,
	.attr_get	= posix_acl_access_get,
	.attr_set	= posix_acl_access_set,
	.attr_remove	= posix_acl_access_remove,
	.attr_exists	= posix_acl_access_exists,
};

static struct attrnames posix_acl_default = {
	.attr_name	= "posix_acl_default",
	.attr_namelen	= sizeof("posix_acl_default") - 1,
	.attr_get	= posix_acl_default_get,
	.attr_set	= posix_acl_default_set,
	.attr_remove	= posix_acl_default_remove,
	.attr_exists	= posix_acl_default_exists,
};

static struct attrnames *attr_system_names[] =
	{ &posix_acl_access, &posix_acl_default };


/*========================================================================
 * Namespace-prefix-style attribute name interface routines.
 *========================================================================*/

STATIC int
attr_generic_set(
	bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
{
	return -xfs_attr_set(xfs_vtoi(vp), name, data, size, xflags);
}

STATIC int
attr_generic_get(
	bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
{
	int	error, asize = size;

	error = xfs_attr_get(xfs_vtoi(vp), name, data,
				    &asize, xflags, NULL);
	if (!error)
		return asize;
	return -error;
}

STATIC int
attr_generic_remove(
	bhv_vnode_t *vp, char *name, int xflags)
{
	return -xfs_attr_remove(xfs_vtoi(vp), name, xflags);
}

STATIC int
attr_generic_listadd(
	attrnames_t		*prefix,
	attrnames_t		*namesp,
	void			*data,
	size_t			size,
	ssize_t			*result)
{
	char			*p = data + *result;

	*result += prefix->attr_namelen;
	*result += namesp->attr_namelen + 1;
	if (!size)
		return 0;
	if (*result > size)
		return -ERANGE;
	strcpy(p, prefix->attr_name);
	p += prefix->attr_namelen;
	strcpy(p, namesp->attr_name);
	p += namesp->attr_namelen + 1;
	return 0;
}

STATIC int
attr_system_list(
	bhv_vnode_t		*vp,
	void			*data,
	size_t			size,
	ssize_t			*result)
{
	attrnames_t		*namesp;
	int			i, error = 0;

	for (i = 0; i < ATTR_SYSCOUNT; i++) {
		namesp = attr_system_names[i];
		if (!namesp->attr_exists || !namesp->attr_exists(vp))
			continue;
		error = attr_generic_listadd(&attr_system, namesp,
						data, size, result);
		if (error)
			break;
	}
	return error;
}

int
attr_generic_list(
	bhv_vnode_t *vp, void *data, size_t size, int xflags, ssize_t *result)
{
	attrlist_cursor_kern_t	cursor = { 0 };
	int			error;

	error = xfs_attr_list(xfs_vtoi(vp), data, size, xflags, &cursor);
	if (error > 0)
		return -error;
	*result = -error;
	return attr_system_list(vp, data, size, result);
}

attrnames_t *
attr_lookup_namespace(
	char			*name,
	struct attrnames	**names,
	int			nnames)
{
	int			i;

	for (i = 0; i < nnames; i++)
		if (!strncmp(name, names[i]->attr_name, names[i]->attr_namelen))
			return names[i];
	return NULL;
}

/*
 * Some checks to prevent people abusing EAs to get over quota:
 * - Don't allow modifying user EAs on devices/symlinks;
 * - Don't allow modifying user EAs if sticky bit set;
 */
STATIC int
attr_user_capable(
	bhv_vnode_t	*vp,
	cred_t		*cred)
{
	struct inode	*inode = vn_to_inode(vp);

	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
		return -EPERM;
	if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode) &&
	    !capable(CAP_SYS_ADMIN))
		return -EPERM;
	if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) &&
	    (current_fsuid(cred) != inode->i_uid) && !capable(CAP_FOWNER))
		return -EPERM;
	return 0;
}

STATIC int
attr_trusted_capable(
	bhv_vnode_t	*vp,
	cred_t		*cred)
{
	struct inode	*inode = vn_to_inode(vp);

	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
		return -EPERM;
	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;
	return 0;
}

STATIC int
attr_system_set(
	bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
{
	attrnames_t	*namesp;
	int		error;

	if (xflags & ATTR_CREATE)
		return -EINVAL;

	namesp = attr_lookup_namespace(name, attr_system_names, ATTR_SYSCOUNT);
	if (!namesp)
		return -EOPNOTSUPP;
	error = namesp->attr_set(vp, name, data, size, xflags);
	if (!error)
		error = vn_revalidate(vp);
	return error;
}

STATIC int
attr_system_get(
	bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
{
	attrnames_t	*namesp;

	namesp = attr_lookup_namespace(name, attr_system_names, ATTR_SYSCOUNT);
	if (!namesp)
		return -EOPNOTSUPP;
	return namesp->attr_get(vp, name, data, size, xflags);
}

STATIC int
attr_system_remove(
	bhv_vnode_t *vp, char *name, int xflags)
{
	attrnames_t	*namesp;

	namesp = attr_lookup_namespace(name, attr_system_names, ATTR_SYSCOUNT);
	if (!namesp)
		return -EOPNOTSUPP;
	return namesp->attr_remove(vp, name, xflags);
}

struct attrnames attr_system = {
	.attr_name	= "system.",
	.attr_namelen	= sizeof("system.") - 1,
	.attr_flag	= ATTR_SYSTEM,
	.attr_get	= attr_system_get,
	.attr_set	= attr_system_set,
	.attr_remove	= attr_system_remove,
	.attr_capable	= (attrcapable_t)fs_noerr,
};

struct attrnames attr_trusted = {
	.attr_name	= "trusted.",
	.attr_namelen	= sizeof("trusted.") - 1,
	.attr_flag	= ATTR_ROOT,
	.attr_get	= attr_generic_get,
	.attr_set	= attr_generic_set,
	.attr_remove	= attr_generic_remove,
	.attr_capable	= attr_trusted_capable,
};

struct attrnames attr_secure = {
	.attr_name	= "security.",
	.attr_namelen	= sizeof("security.") - 1,
	.attr_flag	= ATTR_SECURE,
	.attr_get	= attr_generic_get,
	.attr_set	= attr_generic_set,
	.attr_remove	= attr_generic_remove,
	.attr_capable	= (attrcapable_t)fs_noerr,
};

struct attrnames attr_user = {
	.attr_name	= "user.",
	.attr_namelen	= sizeof("user.") - 1,
	.attr_get	= attr_generic_get,
	.attr_set	= attr_generic_set,
	.attr_remove	= attr_generic_remove,
	.attr_capable	= attr_user_capable,
};

struct attrnames *attr_namespaces[] =
	{ &attr_system, &attr_trusted, &attr_secure, &attr_user };
