/*
 * Copyright (c) 2000-2003,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 "xfs.h"

/*
 * Source file used to associate/disassociate behaviors with virtualized
 * objects.  See xfs_behavior.h for more information about behaviors, etc.
 *
 * The implementation is split between functions in this file and macros
 * in xfs_behavior.h.
 */

/*
 * Insert a new behavior descriptor into a behavior chain.
 *
 * The behavior chain is ordered based on the 'position' number which
 * lives in the first field of the ops vector (higher numbers first).
 *
 * Attempts to insert duplicate ops result in an EINVAL return code.
 * Otherwise, return 0 to indicate success.
 */
int
bhv_insert(bhv_head_t *bhp, bhv_desc_t *bdp)
{
	bhv_desc_t	*curdesc, *prev;
	int		position;

	/*
	 * Validate the position value of the new behavior.
	 */
	position = BHV_POSITION(bdp);
	ASSERT(position >= BHV_POSITION_BASE && position <= BHV_POSITION_TOP);

	/*
	 * Find location to insert behavior.  Check for duplicates.
	 */
	prev = NULL;
	for (curdesc = bhp->bh_first;
	     curdesc != NULL;
	     curdesc = curdesc->bd_next) {

		/* Check for duplication. */
		if (curdesc->bd_ops == bdp->bd_ops) {
			ASSERT(0);
			return EINVAL;
		}

		/* Find correct position */
		if (position >= BHV_POSITION(curdesc)) {
			ASSERT(position != BHV_POSITION(curdesc));
			break;		/* found it */
		}

		prev = curdesc;
	}

	if (prev == NULL) {
		/* insert at front of chain */
		bdp->bd_next = bhp->bh_first;
		bhp->bh_first = bdp;
	} else {
		/* insert after prev */
		bdp->bd_next = prev->bd_next;
		prev->bd_next = bdp;
	}

	return 0;
}

/*
 * Remove a behavior descriptor from a position in a behavior chain;
 * the position is guaranteed not to be the first position.
 * Should only be called by the bhv_remove() macro.
 */
void
bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp)
{
	bhv_desc_t	*curdesc, *prev;

	ASSERT(bhp->bh_first != NULL);
	ASSERT(bhp->bh_first->bd_next != NULL);

	prev = bhp->bh_first;
	for (curdesc = bhp->bh_first->bd_next;
	     curdesc != NULL;
	     curdesc = curdesc->bd_next) {

		if (curdesc == bdp)
			break;		/* found it */
		prev = curdesc;
	}

	ASSERT(curdesc == bdp);
	prev->bd_next = bdp->bd_next;	/* remove from after prev */
}

/*
 * Look for a specific ops vector on the specified behavior chain.
 * Return the associated behavior descriptor.  Or NULL, if not found.
 */
bhv_desc_t *
bhv_lookup(bhv_head_t *bhp, void *ops)
{
	bhv_desc_t	*curdesc;

	for (curdesc = bhp->bh_first;
	     curdesc != NULL;
	     curdesc = curdesc->bd_next) {

		if (curdesc->bd_ops == ops)
			return curdesc;
	}

	return NULL;
}

/*
 * Looks for the first behavior within a specified range of positions.
 * Return the associated behavior descriptor.  Or NULL, if none found.
 */
bhv_desc_t *
bhv_lookup_range(bhv_head_t *bhp, int low, int high)
{
	bhv_desc_t	*curdesc;

	for (curdesc = bhp->bh_first;
	     curdesc != NULL;
	     curdesc = curdesc->bd_next) {

		int	position = BHV_POSITION(curdesc);

		if (position <= high) {
			if (position >= low)
				return curdesc;
			return NULL;
		}
	}

	return NULL;
}

/*
 * Return the base behavior in the chain, or NULL if the chain
 * is empty.
 *
 * The caller has not read locked the behavior chain, so acquire the
 * lock before traversing the chain.
 */
bhv_desc_t *
bhv_base(bhv_head_t *bhp)
{
	bhv_desc_t	*curdesc;

	for (curdesc = bhp->bh_first;
	     curdesc != NULL;
	     curdesc = curdesc->bd_next) {

		if (curdesc->bd_next == NULL) {
			return curdesc;
		}
	}

	return NULL;
}

void
bhv_head_init(
	bhv_head_t *bhp,
	char *name)
{
	bhp->bh_first = NULL;
}

void
bhv_insert_initial(
	bhv_head_t *bhp,
	bhv_desc_t *bdp)
{
	ASSERT(bhp->bh_first == NULL);
	(bhp)->bh_first = bdp;
}

void
bhv_head_destroy(
	bhv_head_t *bhp)
{
	ASSERT(bhp->bh_first == NULL);
}
