/*
 * Copyright (c) 2000-2001 Silicon Graphics, Inc.  All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 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.
 *
 * Further, this software is distributed without any warranty that it is
 * free of the rightful claim of any third person regarding infringement
 * or the like.  Any license provided herein, whether implied or
 * otherwise, applies only to this software file.  Patent licenses, if
 * any, provided herein do not apply to combinations of this program with
 * other software, or any other product whatsoever.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write the Free Software Foundation, Inc., 59
 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
 *
 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
 * Mountain View, CA  94043, or:
 *
 * http://www.sgi.com
 *
 * For further information regarding this notice, see:
 *
 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
 */

#include "xfs.h"

#include "xfs_macros.h"
#include "xfs_types.h"
#include "xfs_inum.h"
#include "xfs_log.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_alloc.h"
#include "xfs_btree.h"
#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_bmap.h"
#include "xfs_da_btree.h"
#include "xfs_dir_leaf.h"
#include "xfs_error.h"

/*
 * xfs_dir.c
 *
 * Provide the external interfaces to manage directories.
 */

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

/*
 * Functions for the dirops interfaces.
 */
static void	xfs_dir_mount(struct xfs_mount *mp);

static int	xfs_dir_isempty(struct xfs_inode *dp);

static int	xfs_dir_init(struct xfs_trans *trans,
			     struct xfs_inode *dir,
			     struct xfs_inode *parent_dir);

static int	xfs_dir_createname(struct xfs_trans *trans,
				   struct xfs_inode *dp,
				   char *name_string,
				   int name_len,
				   xfs_ino_t inode_number,
				   xfs_fsblock_t *firstblock,
				   xfs_bmap_free_t *flist,
				   xfs_extlen_t total);

static int	xfs_dir_lookup(struct xfs_trans *tp,
			       struct xfs_inode *dp,
			       char *name_string,
			       int name_length,
			       xfs_ino_t *inode_number);

static int	xfs_dir_removename(struct xfs_trans *trans,
				   struct xfs_inode *dp,
				   char *name_string,
				   int name_length,
				   xfs_ino_t ino,
				   xfs_fsblock_t *firstblock,
				   xfs_bmap_free_t *flist,
				   xfs_extlen_t total);

static int	xfs_dir_getdents(struct xfs_trans *tp,
				 struct xfs_inode *dp,
				 struct uio *uiop,
				 int *eofp);

static int	xfs_dir_replace(struct xfs_trans *tp,
				struct xfs_inode *dp,
				char *name_string,
				int name_length,
				xfs_ino_t inode_number,
				xfs_fsblock_t *firstblock,
				xfs_bmap_free_t *flist,
				xfs_extlen_t total);

static int	xfs_dir_canenter(struct xfs_trans *tp,
				 struct xfs_inode *dp,
				 char *name_string,
				 int name_length);

static int	xfs_dir_shortform_validate_ondisk(xfs_mount_t *mp,
						  xfs_dinode_t *dip);

xfs_dirops_t xfsv1_dirops = {
	.xd_mount			= xfs_dir_mount,
	.xd_isempty			= xfs_dir_isempty,
	.xd_init			= xfs_dir_init,
	.xd_createname			= xfs_dir_createname,
	.xd_lookup			= xfs_dir_lookup,
	.xd_removename			= xfs_dir_removename,
	.xd_getdents			= xfs_dir_getdents,
	.xd_replace			= xfs_dir_replace,
	.xd_canenter			= xfs_dir_canenter,
	.xd_shortform_validate_ondisk	= xfs_dir_shortform_validate_ondisk,
	.xd_shortform_to_single		= xfs_dir_shortform_to_leaf,
};

/*
 * Internal routines when dirsize == XFS_LBSIZE(mp).
 */
STATIC int xfs_dir_leaf_lookup(xfs_da_args_t *args);
STATIC int xfs_dir_leaf_removename(xfs_da_args_t *args, int *number_entries,
						 int *total_namebytes);
STATIC int xfs_dir_leaf_getdents(xfs_trans_t *trans, xfs_inode_t *dp,
					     uio_t *uio, int *eofp,
					     xfs_dirent_t *dbp,
					     xfs_dir_put_t put);
STATIC int xfs_dir_leaf_replace(xfs_da_args_t *args);

/*
 * Internal routines when dirsize > XFS_LBSIZE(mp).
 */
STATIC int xfs_dir_node_addname(xfs_da_args_t *args);
STATIC int xfs_dir_node_lookup(xfs_da_args_t *args);
STATIC int xfs_dir_node_removename(xfs_da_args_t *args);
STATIC int xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp,
					     uio_t *uio, int *eofp,
					     xfs_dirent_t *dbp,
					     xfs_dir_put_t put);
STATIC int xfs_dir_node_replace(xfs_da_args_t *args);

#if defined(XFS_DIR_TRACE)
ktrace_t *xfs_dir_trace_buf;
#endif


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

xfs_dahash_t	xfs_dir_hash_dot, xfs_dir_hash_dotdot;

/*
 * One-time startup routine called from xfs_init().
 */
void
xfs_dir_startup(void)
{
	xfs_dir_hash_dot = xfs_da_hashname(".", 1);
	xfs_dir_hash_dotdot = xfs_da_hashname("..", 2);
}

/*
 * Initialize directory-related fields in the mount structure.
 */
static void
xfs_dir_mount(xfs_mount_t *mp)
{
	uint shortcount, leafcount, count;

	mp->m_dirversion = 1;
	shortcount = (mp->m_attroffset - (uint)sizeof(xfs_dir_sf_hdr_t)) /
		     (uint)sizeof(xfs_dir_sf_entry_t);
	leafcount = (XFS_LBSIZE(mp) - (uint)sizeof(xfs_dir_leaf_hdr_t)) /
		    ((uint)sizeof(xfs_dir_leaf_entry_t) +
		     (uint)sizeof(xfs_dir_leaf_name_t));
	count = shortcount > leafcount ? shortcount : leafcount;
	mp->m_dircook_elog = xfs_da_log2_roundup(count + 1);
	ASSERT(mp->m_dircook_elog <= mp->m_sb.sb_blocklog);
	mp->m_dir_node_ents = mp->m_attr_node_ents =
		(XFS_LBSIZE(mp) - (uint)sizeof(xfs_da_node_hdr_t)) /
		(uint)sizeof(xfs_da_node_entry_t);
	mp->m_dir_magicpct = (XFS_LBSIZE(mp) * 37) / 100;
	mp->m_dirblksize = mp->m_sb.sb_blocksize;
	mp->m_dirblkfsbs = 1;
}

/*
 * Return 1 if directory contains only "." and "..".
 */
static int
xfs_dir_isempty(xfs_inode_t *dp)
{
	xfs_dir_sf_hdr_t *hdr;

	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
	if (dp->i_d.di_size == 0)
		return(1);
	if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp))
		return(0);
	hdr = (xfs_dir_sf_hdr_t *)dp->i_df.if_u1.if_data;
	return(hdr->count == 0);
}

/*
 * Initialize a directory with its "." and ".." entries.
 */
static int
xfs_dir_init(xfs_trans_t *trans, xfs_inode_t *dir, xfs_inode_t *parent_dir)
{
	xfs_da_args_t args;
	int error;

	memset((char *)&args, 0, sizeof(args));
	args.dp = dir;
	args.trans = trans;

	ASSERT((dir->i_d.di_mode & S_IFMT) == S_IFDIR);
	if ((error = xfs_dir_ino_validate(trans->t_mountp, parent_dir->i_ino)))
		return error;

	return(xfs_dir_shortform_create(&args, parent_dir->i_ino));
}

/*
 * Generic handler routine to add a name to a directory.
 * Transitions directory from shortform to Btree as necessary.
 */
static int							/* error */
xfs_dir_createname(xfs_trans_t *trans, xfs_inode_t *dp, char *name,
		   int namelen, xfs_ino_t inum, xfs_fsblock_t *firstblock,
		   xfs_bmap_free_t *flist, xfs_extlen_t total)
{
	xfs_da_args_t args;
	int retval, newsize, done;

	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);

	if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum)))
		return (retval);

	XFS_STATS_INC(xs_dir_create);
	/*
	 * Fill in the arg structure for this request.
	 */
	args.name = name;
	args.namelen = namelen;
	args.hashval = xfs_da_hashname(name, namelen);
	args.inumber = inum;
	args.dp = dp;
	args.firstblock = firstblock;
	args.flist = flist;
	args.total = total;
	args.whichfork = XFS_DATA_FORK;
	args.trans = trans;
	args.justcheck = 0;
	args.addname = args.oknoent = 1;

	/*
	 * Decide on what work routines to call based on the inode size.
	 */
	done = 0;
	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
		newsize = XFS_DIR_SF_ENTSIZE_BYNAME(args.namelen);
		if ((dp->i_d.di_size + newsize) <= XFS_IFORK_DSIZE(dp)) {
			retval = xfs_dir_shortform_addname(&args);
			done = 1;
		} else {
			if (total == 0)
				return XFS_ERROR(ENOSPC);
			retval = xfs_dir_shortform_to_leaf(&args);
			done = retval != 0;
		}
	}
	if (!done && xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
		retval = xfs_dir_leaf_addname(&args);
		done = retval != ENOSPC;
		if (!done) {
			if (total == 0)
				return XFS_ERROR(ENOSPC);
			retval = xfs_dir_leaf_to_node(&args);
			done = retval != 0;
		}
	}
	if (!done) {
		retval = xfs_dir_node_addname(&args);
	}
	return(retval);
}

/*
 * Generic handler routine to check if a name can be added to a directory,
 * without adding any blocks to the directory.
 */
static int							/* error */
xfs_dir_canenter(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen)
{
	xfs_da_args_t args;
	int retval, newsize;

	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
	/*
	 * Fill in the arg structure for this request.
	 */
	args.name = name;
	args.namelen = namelen;
	args.hashval = xfs_da_hashname(name, namelen);
	args.inumber = 0;
	args.dp = dp;
	args.firstblock = NULL;
	args.flist = NULL;
	args.total = 0;
	args.whichfork = XFS_DATA_FORK;
	args.trans = trans;
	args.justcheck = args.addname = args.oknoent = 1;

	/*
	 * Decide on what work routines to call based on the inode size.
	 */
	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
		newsize = XFS_DIR_SF_ENTSIZE_BYNAME(args.namelen);
		if ((dp->i_d.di_size + newsize) <= XFS_IFORK_DSIZE(dp))
			retval = 0;
		else
			retval = XFS_ERROR(ENOSPC);
	} else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
		retval = xfs_dir_leaf_addname(&args);
	} else {
		retval = xfs_dir_node_addname(&args);
	}
	return(retval);
}

/*
 * Generic handler routine to remove a name from a directory.
 * Transitions directory from Btree to shortform as necessary.
 */
static int							/* error */
xfs_dir_removename(xfs_trans_t *trans, xfs_inode_t *dp, char *name,
		   int namelen, xfs_ino_t ino, xfs_fsblock_t *firstblock,
		   xfs_bmap_free_t *flist, xfs_extlen_t total)
{
	xfs_da_args_t args;
	int count, totallen, newsize, retval;

	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
	XFS_STATS_INC(xs_dir_remove);
	/*
	 * Fill in the arg structure for this request.
	 */
	args.name = name;
	args.namelen = namelen;
	args.hashval = xfs_da_hashname(name, namelen);
	args.inumber = ino;
	args.dp = dp;
	args.firstblock = firstblock;
	args.flist = flist;
	args.total = total;
	args.whichfork = XFS_DATA_FORK;
	args.trans = trans;
	args.justcheck = args.addname = args.oknoent = 0;

	/*
	 * Decide on what work routines to call based on the inode size.
	 */
	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
		retval = xfs_dir_shortform_removename(&args);
	} else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
		retval = xfs_dir_leaf_removename(&args, &count, &totallen);
		if (retval == 0) {
			newsize = XFS_DIR_SF_ALLFIT(count, totallen);
			if (newsize <= XFS_IFORK_DSIZE(dp)) {
				retval = xfs_dir_leaf_to_shortform(&args);
			}
		}
	} else {
		retval = xfs_dir_node_removename(&args);
	}
	return(retval);
}

static int							/* error */
xfs_dir_lookup(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen,
				   xfs_ino_t *inum)
{
	xfs_da_args_t args;
	int retval;

	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);

	XFS_STATS_INC(xs_dir_lookup);
	/*
	 * Fill in the arg structure for this request.
	 */
	args.name = name;
	args.namelen = namelen;
	args.hashval = xfs_da_hashname(name, namelen);
	args.inumber = 0;
	args.dp = dp;
	args.firstblock = NULL;
	args.flist = NULL;
	args.total = 0;
	args.whichfork = XFS_DATA_FORK;
	args.trans = trans;
	args.justcheck = args.addname = 0;
	args.oknoent = 1;

	/*
	 * Decide on what work routines to call based on the inode size.
	 */
	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
		retval = xfs_dir_shortform_lookup(&args);
	} else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
		retval = xfs_dir_leaf_lookup(&args);
	} else {
		retval = xfs_dir_node_lookup(&args);
	}
	if (retval == EEXIST)
		retval = 0;
	*inum = args.inumber;
	return(retval);
}

/*
 * Implement readdir.
 */
static int							/* error */
xfs_dir_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio, int *eofp)
{
	xfs_dirent_t *dbp;
	int  alignment, retval;
	xfs_dir_put_t put;

	XFS_STATS_INC(xs_dir_getdents);
	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);

	/*
	 * If our caller has given us a single contiguous memory buffer,
	 * just work directly within that buffer.  If it's in user memory,
	 * lock it down first.
	 */
	alignment = sizeof(xfs_off_t) - 1;
	if ((uio->uio_iovcnt == 1) &&
	    (((__psint_t)uio->uio_iov[0].iov_base & alignment) == 0) &&
	    ((uio->uio_iov[0].iov_len & alignment) == 0)) {
		dbp = NULL;
		put = xfs_dir_put_dirent64_direct;
	} else {
		dbp = kmem_alloc(sizeof(*dbp) + MAXNAMELEN, KM_SLEEP);
		put = xfs_dir_put_dirent64_uio;
	}

	/*
	 * Decide on what work routines to call based on the inode size.
	 */
	*eofp = 0;

	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
		retval = xfs_dir_shortform_getdents(dp, uio, eofp, dbp, put);
	} else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
		retval = xfs_dir_leaf_getdents(trans, dp, uio, eofp, dbp, put);
	} else {
		retval = xfs_dir_node_getdents(trans, dp, uio, eofp, dbp, put);
	}
	if (dbp != NULL)
		kmem_free(dbp, sizeof(*dbp) + MAXNAMELEN);

	return(retval);
}

static int							/* error */
xfs_dir_replace(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen,
				    xfs_ino_t inum, xfs_fsblock_t *firstblock,
				    xfs_bmap_free_t *flist, xfs_extlen_t total)
{
	xfs_da_args_t args;
	int retval;

	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);

	if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum)))
		return retval;

	/*
	 * Fill in the arg structure for this request.
	 */
	args.name = name;
	args.namelen = namelen;
	args.hashval = xfs_da_hashname(name, namelen);
	args.inumber = inum;
	args.dp = dp;
	args.firstblock = firstblock;
	args.flist = flist;
	args.total = total;
	args.whichfork = XFS_DATA_FORK;
	args.trans = trans;
	args.justcheck = args.addname = args.oknoent = 0;

	/*
	 * Decide on what work routines to call based on the inode size.
	 */
	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
		retval = xfs_dir_shortform_replace(&args);
	} else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
		retval = xfs_dir_leaf_replace(&args);
	} else {
		retval = xfs_dir_node_replace(&args);
	}

	return(retval);
}

static int
xfs_dir_shortform_validate_ondisk(xfs_mount_t *mp, xfs_dinode_t *dp)
{
	xfs_ino_t		ino;
	int			namelen_sum;
	int			count;
	xfs_dir_shortform_t	*sf;
	xfs_dir_sf_entry_t	*sfe;
	int			i;



	if ((INT_GET(dp->di_core.di_mode, ARCH_CONVERT) & S_IFMT) != S_IFDIR) {
		return 0;
	}
	if (INT_GET(dp->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_LOCAL) {
		return 0;
	}
	if (INT_GET(dp->di_core.di_size, ARCH_CONVERT) < sizeof(sf->hdr)) {
		xfs_fs_cmn_err(CE_WARN, mp, "Invalid shortform size: dp 0x%p",
			dp);
		return 1;
	}
	sf = (xfs_dir_shortform_t *)(&dp->di_u.di_dirsf);
	ino = XFS_GET_DIR_INO8(sf->hdr.parent);
	if (xfs_dir_ino_validate(mp, ino))
		return 1;

	count =	sf->hdr.count;
	if ((count < 0) || ((count * 10) > XFS_LITINO(mp))) {
		xfs_fs_cmn_err(CE_WARN, mp,
			"Invalid shortform count: dp 0x%p", dp);
		return(1);
	}

	if (count == 0) {
		return 0;
	}

	namelen_sum = 0;
	sfe = &sf->list[0];
	for (i = sf->hdr.count - 1; i >= 0; i--) {
		ino = XFS_GET_DIR_INO8(sfe->inumber);
		xfs_dir_ino_validate(mp, ino);
		if (sfe->namelen >= XFS_LITINO(mp)) {
			xfs_fs_cmn_err(CE_WARN, mp,
				"Invalid shortform namelen: dp 0x%p", dp);
			return 1;
		}
		namelen_sum += sfe->namelen;
		sfe = XFS_DIR_SF_NEXTENTRY(sfe);
	}
	if (namelen_sum >= XFS_LITINO(mp)) {
		xfs_fs_cmn_err(CE_WARN, mp,
			"Invalid shortform namelen: dp 0x%p", dp);
		return 1;
	}

	return 0;
}

/*========================================================================
 * External routines when dirsize == XFS_LBSIZE(dp->i_mount).
 *========================================================================*/

/*
 * Add a name to the leaf directory structure
 * This is the external routine.
 */
int
xfs_dir_leaf_addname(xfs_da_args_t *args)
{
	int index, retval;
	xfs_dabuf_t *bp;

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

	retval = xfs_dir_leaf_lookup_int(bp, args, &index);
	if (retval == ENOENT)
		retval = xfs_dir_leaf_add(bp, args, index);
	xfs_da_buf_done(bp);
	return(retval);
}

/*
 * Remove a name from the leaf directory structure
 * This is the external routine.
 */
STATIC int
xfs_dir_leaf_removename(xfs_da_args_t *args, int *count, int *totallen)
{
	xfs_dir_leafblock_t *leaf;
	int index, retval;
	xfs_dabuf_t *bp;

	retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
					      XFS_DATA_FORK);
	if (retval)
		return(retval);
	ASSERT(bp != NULL);
	leaf = bp->data;
	ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC);
	retval = xfs_dir_leaf_lookup_int(bp, args, &index);
	if (retval == EEXIST) {
		(void)xfs_dir_leaf_remove(args->trans, bp, index);
		*count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
		*totallen = INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
		retval = 0;
	}
	xfs_da_buf_done(bp);
	return(retval);
}

/*
 * Look up a name in a leaf directory structure.
 * This is the external routine.
 */
STATIC int
xfs_dir_leaf_lookup(xfs_da_args_t *args)
{
	int index, retval;
	xfs_dabuf_t *bp;

	retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
					      XFS_DATA_FORK);
	if (retval)
		return(retval);
	ASSERT(bp != NULL);
	retval = xfs_dir_leaf_lookup_int(bp, args, &index);
	xfs_da_brelse(args->trans, bp);
	return(retval);
}

/*
 * Copy out directory entries for getdents(), for leaf directories.
 */
STATIC int
xfs_dir_leaf_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio,
				  int *eofp, xfs_dirent_t *dbp, xfs_dir_put_t put)
{
	xfs_dabuf_t *bp;
	int retval, eob;

	retval = xfs_da_read_buf(dp->i_transp, dp, 0, -1, &bp, XFS_DATA_FORK);
	if (retval)
		return(retval);
	ASSERT(bp != NULL);
	retval = xfs_dir_leaf_getdents_int(bp, dp, 0, uio, &eob, dbp, put, -1);
	xfs_da_brelse(trans, bp);
	*eofp = (eob == 0);
	return(retval);
}

/*
 * Look up a name in a leaf directory structure, replace the inode number.
 * This is the external routine.
 */
STATIC int
xfs_dir_leaf_replace(xfs_da_args_t *args)
{
	int index, retval;
	xfs_dabuf_t *bp;
	xfs_ino_t inum;
	xfs_dir_leafblock_t *leaf;
	xfs_dir_leaf_entry_t *entry;
	xfs_dir_leaf_name_t *namest;

	inum = args->inumber;
	retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
					      XFS_DATA_FORK);
	if (retval)
		return(retval);
	ASSERT(bp != NULL);
	retval = xfs_dir_leaf_lookup_int(bp, args, &index);
	if (retval == EEXIST) {
		leaf = bp->data;
		entry = &leaf->entries[index];
		namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
		/* XXX - replace assert? */
		XFS_DIR_SF_PUT_DIRINO(&inum, &namest->inumber);
		xfs_da_log_buf(args->trans, bp,
		    XFS_DA_LOGRANGE(leaf, namest, sizeof(namest->inumber)));
		xfs_da_buf_done(bp);
		retval = 0;
	} else
		xfs_da_brelse(args->trans, bp);
	return(retval);
}


/*========================================================================
 * External routines when dirsize > XFS_LBSIZE(mp).
 *========================================================================*/

/*
 * Add a name to a Btree-format directory.
 *
 * 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).
 */
STATIC int
xfs_dir_node_addname(xfs_da_args_t *args)
{
	xfs_da_state_t *state;
	xfs_da_state_blk_t *blk;
	int retval, error;

	/*
	 * Fill in bucket of arguments/results/context to carry around.
	 */
	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_dir_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)
		retval = error;
	if (retval != ENOENT)
		goto error;
	blk = &state->path.blk[ state->path.active-1 ];
	ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC);
	retval = xfs_dir_leaf_add(blk->bp, args, blk->index);
	if (retval == 0) {
		/*
		 * Addition succeeded, update Btree hashvals.
		 */
		if (!args->justcheck)
			xfs_da_fixhashpath(state, &state->path);
	} else {
		/*
		 * Addition failed, split as many Btree elements as required.
		 */
		if (args->total == 0) {
			ASSERT(retval == ENOSPC);
			goto error;
		}
		retval = xfs_da_split(state);
	}
error:
	xfs_da_state_free(state);

	return(retval);
}

/*
 * Remove a name from a B-tree directory.
 *
 * 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_dir_node_removename(xfs_da_args_t *args)
{
	xfs_da_state_t *state;
	xfs_da_state_blk_t *blk;
	int retval, error;

	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_dir_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;
	if (retval != EEXIST) {
		xfs_da_state_free(state);
		return(retval);
	}

	/*
	 * Remove the name and update the hashvals in the tree.
	 */
	blk = &state->path.blk[ state->path.active-1 ];
	ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC);
	retval = xfs_dir_leaf_remove(args->trans, blk->bp, blk->index);
	xfs_da_fixhashpath(state, &state->path);

	/*
	 * Check to see if the tree needs to be collapsed.
	 */
	error = 0;
	if (retval) {
		error = xfs_da_join(state);
	}

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

/*
 * Look up a filename in a int directory.
 * Use an internal routine to actually do all the work.
 */
STATIC int
xfs_dir_node_lookup(xfs_da_args_t *args)
{
	xfs_da_state_t *state;
	int retval, error, 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_dir_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;
	}

	/*
	 * 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
xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio,
				  int *eofp, xfs_dirent_t *dbp, xfs_dir_put_t put)
{
	xfs_da_intnode_t *node;
	xfs_da_node_entry_t *btree;
	xfs_dir_leafblock_t *leaf = NULL;
	xfs_dablk_t bno, nextbno;
	xfs_dahash_t cookhash;
	xfs_mount_t *mp;
	int error, eob, i;
	xfs_dabuf_t *bp;
	xfs_daddr_t nextda;

	/*
	 * Pick up our context.
	 */
	mp = dp->i_mount;
	bp = NULL;
	bno = XFS_DA_COOKIE_BNO(mp, uio->uio_offset);
	cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset);

	xfs_dir_trace_g_du("node: start", dp, uio);

	/*
	 * Re-find our place, even if we're confused about what our place is.
	 *
	 * First we check the block number from the magic cookie, it is a
	 * cache of where we ended last time.  If we find a leaf block, and
	 * the starting hashval in that block is less than our desired
	 * hashval, then we run with it.
	 */
	if (bno > 0) {
		error = xfs_da_read_buf(trans, dp, bno, -2, &bp, XFS_DATA_FORK);
		if ((error != 0) && (error != EFSCORRUPTED))
			return(error);
		if (bp)
			leaf = bp->data;
		if (bp && INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != XFS_DIR_LEAF_MAGIC) {
			xfs_dir_trace_g_dub("node: block not a leaf",
						   dp, uio, bno);
			xfs_da_brelse(trans, bp);
			bp = NULL;
		}
		if (bp && INT_GET(leaf->entries[0].hashval, ARCH_CONVERT) > cookhash) {
			xfs_dir_trace_g_dub("node: leaf hash too large",
						   dp, uio, bno);
			xfs_da_brelse(trans, bp);
			bp = NULL;
		}
		if (bp &&
		    cookhash > INT_GET(leaf->entries[INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT)) {
			xfs_dir_trace_g_dub("node: leaf hash too small",
						   dp, uio, bno);
			xfs_da_brelse(trans, bp);
			bp = NULL;
		}
	}

	/*
	 * If we did not find a leaf block from the blockno in the cookie,
	 * or we there was no blockno in the cookie (eg: first time thru),
	 * the we start at the top of the Btree and re-find our hashval.
	 */
	if (bp == NULL) {
		xfs_dir_trace_g_du("node: start at root" , dp, uio);
		bno = 0;
		for (;;) {
			error = xfs_da_read_buf(trans, dp, bno, -1, &bp,
						       XFS_DATA_FORK);
			if (error)
				return(error);
			if (bp == NULL)
				return(XFS_ERROR(EFSCORRUPTED));
			node = bp->data;
			if (INT_GET(node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC)
				break;
			btree = &node->btree[0];
			xfs_dir_trace_g_dun("node: node detail", dp, uio, node);
			for (i = 0; i < INT_GET(node->hdr.count, ARCH_CONVERT); btree++, i++) {
				if (INT_GET(btree->hashval, ARCH_CONVERT) >= cookhash) {
					bno = INT_GET(btree->before, ARCH_CONVERT);
					break;
				}
			}
			if (i == INT_GET(node->hdr.count, ARCH_CONVERT)) {
				xfs_da_brelse(trans, bp);
				xfs_dir_trace_g_du("node: hash beyond EOF",
							  dp, uio);
				uio->uio_offset = XFS_DA_MAKE_COOKIE(mp, 0, 0,
							     XFS_DA_MAXHASH);
				*eofp = 1;
				return(0);
			}
			xfs_dir_trace_g_dub("node: going to block",
						   dp, uio, bno);
			xfs_da_brelse(trans, bp);
		}
	}
	ASSERT(cookhash != XFS_DA_MAXHASH);

	/*
	 * We've dropped down to the (first) leaf block that contains the
	 * hashval we are interested in.  Continue rolling upward thru the
	 * leaf blocks until we fill up our buffer.
	 */
	for (;;) {
		leaf = bp->data;
		if (unlikely(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != XFS_DIR_LEAF_MAGIC)) {
			xfs_dir_trace_g_dul("node: not a leaf", dp, uio, leaf);
			xfs_da_brelse(trans, bp);
			XFS_CORRUPTION_ERROR("xfs_dir_node_getdents(1)",
					     XFS_ERRLEVEL_LOW, mp, leaf);
			return XFS_ERROR(EFSCORRUPTED);
		}
		xfs_dir_trace_g_dul("node: leaf detail", dp, uio, leaf);
		if ((nextbno = INT_GET(leaf->hdr.info.forw, ARCH_CONVERT))) {
			nextda = xfs_da_reada_buf(trans, dp, nextbno,
						  XFS_DATA_FORK);
		} else
			nextda = -1;
		error = xfs_dir_leaf_getdents_int(bp, dp, bno, uio, &eob, dbp,
						  put, nextda);
		xfs_da_brelse(trans, bp);
		bno = nextbno;
		if (eob) {
			xfs_dir_trace_g_dub("node: E-O-B", dp, uio, bno);
			*eofp = 0;
			return(error);
		}
		if (bno == 0)
			break;
		error = xfs_da_read_buf(trans, dp, bno, nextda, &bp,
					XFS_DATA_FORK);
		if (error)
			return(error);
		if (unlikely(bp == NULL)) {
			XFS_ERROR_REPORT("xfs_dir_node_getdents(2)",
					 XFS_ERRLEVEL_LOW, mp);
			return(XFS_ERROR(EFSCORRUPTED));
		}
	}
	*eofp = 1;
	xfs_dir_trace_g_du("node: E-O-F", dp, uio);
	return(0);
}

/*
 * Look up a filename in an int directory, replace the inode number.
 * Use an internal routine to actually do the lookup.
 */
STATIC int
xfs_dir_node_replace(xfs_da_args_t *args)
{
	xfs_da_state_t *state;
	xfs_da_state_blk_t *blk;
	xfs_dir_leafblock_t *leaf;
	xfs_dir_leaf_entry_t *entry;
	xfs_dir_leaf_name_t *namest;
	xfs_ino_t inum;
	int retval, error, i;
	xfs_dabuf_t *bp;

	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_dir_node_ents;
	inum = args->inumber;

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

	if (retval == EEXIST) {
		blk = &state->path.blk[state->path.active - 1];
		ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC);
		bp = blk->bp;
		leaf = bp->data;
		entry = &leaf->entries[blk->index];
		namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
		/* XXX - replace assert ? */
		XFS_DIR_SF_PUT_DIRINO(&inum, &namest->inumber);
		xfs_da_log_buf(args->trans, bp,
		    XFS_DA_LOGRANGE(leaf, namest, sizeof(namest->inumber)));
		xfs_da_buf_done(bp);
		blk->bp = NULL;
		retval = 0;
	} else {
		i = state->path.active - 1;
		xfs_da_brelse(args->trans, state->path.blk[i].bp);
		state->path.blk[i].bp = NULL;
	}
	for (i = 0; i < state->path.active - 1; i++) {
		xfs_da_brelse(args->trans, state->path.blk[i].bp);
		state->path.blk[i].bp = NULL;
	}

	xfs_da_state_free(state);
	return(retval);
}

#if defined(XFS_DIR_TRACE)
/*
 * Add a trace buffer entry for an inode and a uio.
 */
void
xfs_dir_trace_g_du(char *where, xfs_inode_t *dp, uio_t *uio)
{
	xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DU, where,
		     (void *)dp, (void *)dp->i_mount,
		     (void *)((unsigned long)(uio->uio_offset >> 32)),
		     (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
		     (void *)(unsigned long)uio->uio_resid,
		     NULL, NULL, NULL, NULL, NULL, NULL, NULL);
}

/*
 * Add a trace buffer entry for an inode and a uio.
 */
void
xfs_dir_trace_g_dub(char *where, xfs_inode_t *dp, uio_t *uio, xfs_dablk_t bno)
{
	xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUB, where,
		     (void *)dp, (void *)dp->i_mount,
		     (void *)((unsigned long)(uio->uio_offset >> 32)),
		     (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
		     (void *)(unsigned long)uio->uio_resid,
		     (void *)(unsigned long)bno,
		     NULL, NULL, NULL, NULL, NULL, NULL);
}

/*
 * Add a trace buffer entry for an inode and a uio.
 */
void
xfs_dir_trace_g_dun(char *where, xfs_inode_t *dp, uio_t *uio,
			xfs_da_intnode_t *node)
{
	int	last = INT_GET(node->hdr.count, ARCH_CONVERT) - 1;

	xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUN, where,
		     (void *)dp, (void *)dp->i_mount,
		     (void *)((unsigned long)(uio->uio_offset >> 32)),
		     (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
		     (void *)(unsigned long)uio->uio_resid,
		     (void *)(unsigned long)
			INT_GET(node->hdr.info.forw, ARCH_CONVERT),
		     (void *)(unsigned long)
			INT_GET(node->hdr.count, ARCH_CONVERT),
		     (void *)(unsigned long)
			INT_GET(node->btree[0].hashval, ARCH_CONVERT),
		     (void *)(unsigned long)
			INT_GET(node->btree[last].hashval, ARCH_CONVERT),
		     NULL, NULL, NULL);
}

/*
 * Add a trace buffer entry for an inode and a uio.
 */
void
xfs_dir_trace_g_dul(char *where, xfs_inode_t *dp, uio_t *uio,
			xfs_dir_leafblock_t *leaf)
{
	int	last = INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1;

	xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUL, where,
		     (void *)dp, (void *)dp->i_mount,
		     (void *)((unsigned long)(uio->uio_offset >> 32)),
		     (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
		     (void *)(unsigned long)uio->uio_resid,
		     (void *)(unsigned long)
			INT_GET(leaf->hdr.info.forw, ARCH_CONVERT),
		     (void *)(unsigned long)
			INT_GET(leaf->hdr.count, ARCH_CONVERT),
		     (void *)(unsigned long)
			INT_GET(leaf->entries[0].hashval, ARCH_CONVERT),
		     (void *)(unsigned long)
			INT_GET(leaf->entries[last].hashval, ARCH_CONVERT),
		     NULL, NULL, NULL);
}

/*
 * Add a trace buffer entry for an inode and a uio.
 */
void
xfs_dir_trace_g_due(char *where, xfs_inode_t *dp, uio_t *uio,
			xfs_dir_leaf_entry_t *entry)
{
	xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUE, where,
		     (void *)dp, (void *)dp->i_mount,
		     (void *)((unsigned long)(uio->uio_offset >> 32)),
		     (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
		     (void *)(unsigned long)uio->uio_resid,
		     (void *)(unsigned long)
			INT_GET(entry->hashval, ARCH_CONVERT),
		     NULL, NULL, NULL, NULL, NULL, NULL);
}

/*
 * Add a trace buffer entry for an inode and a uio.
 */
void
xfs_dir_trace_g_duc(char *where, xfs_inode_t *dp, uio_t *uio, xfs_off_t cookie)
{
	xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUC, where,
		     (void *)dp, (void *)dp->i_mount,
		     (void *)((unsigned long)(uio->uio_offset >> 32)),
		     (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
		     (void *)(unsigned long)uio->uio_resid,
		     (void *)((unsigned long)(cookie >> 32)),
		     (void *)((unsigned long)(cookie & 0xFFFFFFFF)),
		     NULL, NULL, NULL, NULL, NULL);
}

/*
 * Add a trace buffer entry for the arguments given to the routine,
 * generic form.
 */
void
xfs_dir_trace_enter(int type, char *where,
			void * a0, void * a1,
			void * a2, void * a3,
			void * a4, void * a5,
			void * a6, void * a7,
			void * a8, void * a9,
			void * a10, void * a11)
{
	ASSERT(xfs_dir_trace_buf);
	ktrace_enter(xfs_dir_trace_buf, (void *)(unsigned long)type,
					(void *)where,
					(void *)a0, (void *)a1, (void *)a2,
					(void *)a3, (void *)a4, (void *)a5,
					(void *)a6, (void *)a7, (void *)a8,
					(void *)a9, (void *)a10, (void *)a11,
					NULL, NULL);
}
#endif	/* XFS_DIR_TRACE */
