/*
 * Copyright (c) 2000-2001,2004-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 "libxfs.h"
#include "bit.h"
#include "type.h"
#include "faddr.h"
#include "fprint.h"
#include "field.h"
#include "attr.h"
#include "io.h"
#include "init.h"
#include "output.h"

static int	attr_leaf_entries_count(void *obj, int startoff);
static int	attr_leaf_hdr_count(void *obj, int startoff);
static int	attr_leaf_name_local_count(void *obj, int startoff);
static int	attr_leaf_name_local_name_count(void *obj, int startoff);
static int	attr_leaf_name_local_value_count(void *obj, int startoff);
static int	attr_leaf_name_local_value_offset(void *obj, int startoff,
						  int idx);
static int	attr_leaf_name_remote_count(void *obj, int startoff);
static int	attr_leaf_name_remote_name_count(void *obj, int startoff);
static int	attr_leaf_nvlist_count(void *obj, int startoff);
static int	attr_leaf_nvlist_offset(void *obj, int startoff, int idx);
static int	attr_node_btree_count(void *obj, int startoff);
static int	attr_node_hdr_count(void *obj, int startoff);

const field_t	attr_hfld[] = {
	{ "", FLDT_ATTR, OI(0), C1, 0, TYP_NONE },
	{ NULL }
};

#define	LOFF(f)	bitize(offsetof(xfs_attr_leafblock_t, f))
#define	NOFF(f)	bitize(offsetof(xfs_da_intnode_t, f))
const field_t	attr_flds[] = {
	{ "hdr", FLDT_ATTR_LEAF_HDR, OI(LOFF(hdr)), attr_leaf_hdr_count,
	  FLD_COUNT, TYP_NONE },
	{ "hdr", FLDT_ATTR_NODE_HDR, OI(NOFF(hdr)), attr_node_hdr_count,
	  FLD_COUNT, TYP_NONE },
	{ "entries", FLDT_ATTR_LEAF_ENTRY, OI(LOFF(entries)),
	  attr_leaf_entries_count, FLD_ARRAY|FLD_COUNT, TYP_NONE },
	{ "btree", FLDT_ATTR_NODE_ENTRY, OI(NOFF(__btree)), attr_node_btree_count,
	  FLD_ARRAY|FLD_COUNT, TYP_NONE },
	{ "nvlist", FLDT_ATTR_LEAF_NAME, attr_leaf_nvlist_offset,
	  attr_leaf_nvlist_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE },
	{ NULL }
};

#define	BOFF(f)	bitize(offsetof(xfs_da_blkinfo_t, f))
const field_t	attr_blkinfo_flds[] = {
	{ "forw", FLDT_ATTRBLOCK, OI(BOFF(forw)), C1, 0, TYP_ATTR },
	{ "back", FLDT_ATTRBLOCK, OI(BOFF(back)), C1, 0, TYP_ATTR },
	{ "magic", FLDT_UINT16X, OI(BOFF(magic)), C1, 0, TYP_NONE },
	{ "pad", FLDT_UINT16X, OI(BOFF(pad)), C1, FLD_SKIPALL, TYP_NONE },
	{ NULL }
};

#define	LEOFF(f)	bitize(offsetof(xfs_attr_leaf_entry_t, f))
const field_t	attr_leaf_entry_flds[] = {
	{ "hashval", FLDT_UINT32X, OI(LEOFF(hashval)), C1, 0, TYP_NONE },
	{ "nameidx", FLDT_UINT16D, OI(LEOFF(nameidx)), C1, 0, TYP_NONE },
	{ "flags", FLDT_UINT8X, OI(LEOFF(flags)), C1, FLD_SKIPALL, TYP_NONE },
	{ "incomplete", FLDT_UINT1,
	  OI(LEOFF(flags) + bitsz(__uint8_t) - XFS_ATTR_INCOMPLETE_BIT - 1), C1,
	  0, TYP_NONE },
	{ "root", FLDT_UINT1,
	  OI(LEOFF(flags) + bitsz(__uint8_t) - XFS_ATTR_ROOT_BIT - 1), C1, 0,
	  TYP_NONE },
	{ "secure", FLDT_UINT1,
	  OI(LEOFF(flags) + bitsz(__uint8_t) - XFS_ATTR_SECURE_BIT - 1), C1, 0,
	  TYP_NONE },
	{ "local", FLDT_UINT1,
	  OI(LEOFF(flags) + bitsz(__uint8_t) - XFS_ATTR_LOCAL_BIT - 1), C1, 0,
	  TYP_NONE },
	{ "pad2", FLDT_UINT8X, OI(LEOFF(pad2)), C1, FLD_SKIPALL, TYP_NONE },
	{ NULL }
};

#define	LHOFF(f)	bitize(offsetof(xfs_attr_leaf_hdr_t, f))
const field_t	attr_leaf_hdr_flds[] = {
	{ "info", FLDT_ATTR_BLKINFO, OI(LHOFF(info)), C1, 0, TYP_NONE },
	{ "count", FLDT_UINT16D, OI(LHOFF(count)), C1, 0, TYP_NONE },
	{ "usedbytes", FLDT_UINT16D, OI(LHOFF(usedbytes)), C1, 0, TYP_NONE },
	{ "firstused", FLDT_UINT16D, OI(LHOFF(firstused)), C1, 0, TYP_NONE },
	{ "holes", FLDT_UINT8D, OI(LHOFF(holes)), C1, 0, TYP_NONE },
	{ "pad1", FLDT_UINT8X, OI(LHOFF(pad1)), C1, FLD_SKIPALL, TYP_NONE },
	{ "freemap", FLDT_ATTR_LEAF_MAP, OI(LHOFF(freemap)),
	  CI(XFS_ATTR_LEAF_MAPSIZE), FLD_ARRAY, TYP_NONE },
	{ NULL }
};

#define	LMOFF(f)	bitize(offsetof(xfs_attr_leaf_map_t, f))
const field_t	attr_leaf_map_flds[] = {
	{ "base", FLDT_UINT16D, OI(LMOFF(base)), C1, 0, TYP_NONE },
	{ "size", FLDT_UINT16D, OI(LMOFF(size)), C1, 0, TYP_NONE },
	{ NULL }
};

#define	LNOFF(f)	bitize(offsetof(xfs_attr_leaf_name_local_t, f))
#define	LVOFF(f)	bitize(offsetof(xfs_attr_leaf_name_remote_t, f))
const field_t	attr_leaf_name_flds[] = {
	{ "valuelen", FLDT_UINT16D, OI(LNOFF(valuelen)),
	  attr_leaf_name_local_count, FLD_COUNT, TYP_NONE },
	{ "namelen", FLDT_UINT8D, OI(LNOFF(namelen)),
	  attr_leaf_name_local_count, FLD_COUNT, TYP_NONE },
	{ "name", FLDT_CHARNS, OI(LNOFF(nameval)),
	  attr_leaf_name_local_name_count, FLD_COUNT, TYP_NONE },
	{ "value", FLDT_CHARNS, attr_leaf_name_local_value_offset,
	  attr_leaf_name_local_value_count, FLD_COUNT|FLD_OFFSET, TYP_NONE },
	{ "valueblk", FLDT_UINT32X, OI(LVOFF(valueblk)),
	  attr_leaf_name_remote_count, FLD_COUNT, TYP_NONE },
	{ "valuelen", FLDT_UINT32D, OI(LVOFF(valuelen)),
	  attr_leaf_name_remote_count, FLD_COUNT, TYP_NONE },
	{ "namelen", FLDT_UINT8D, OI(LVOFF(namelen)),
	  attr_leaf_name_remote_count, FLD_COUNT, TYP_NONE },
	{ "name", FLDT_CHARNS, OI(LVOFF(name)),
	  attr_leaf_name_remote_name_count, FLD_COUNT, TYP_NONE },
	{ NULL }
};

#define	EOFF(f)	bitize(offsetof(xfs_da_node_entry_t, f))
const field_t	attr_node_entry_flds[] = {
	{ "hashval", FLDT_UINT32X, OI(EOFF(hashval)), C1, 0, TYP_NONE },
	{ "before", FLDT_ATTRBLOCK, OI(EOFF(before)), C1, 0, TYP_ATTR },
	{ NULL }
};

#define	HOFF(f)	bitize(offsetof(xfs_da_node_hdr_t, f))
const field_t	attr_node_hdr_flds[] = {
	{ "info", FLDT_ATTR_BLKINFO, OI(HOFF(info)), C1, 0, TYP_NONE },
	{ "count", FLDT_UINT16D, OI(HOFF(__count)), C1, 0, TYP_NONE },
	{ "level", FLDT_UINT16D, OI(HOFF(__level)), C1, 0, TYP_NONE },
	{ NULL }
};

static int
attr_leaf_entries_count(
	void			*obj,
	int			startoff)
{
	struct xfs_attr_leafblock *leaf = obj;

	ASSERT(startoff == 0);
	if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC)
		return 0;
	return be16_to_cpu(leaf->hdr.count);
}

static int
attr3_leaf_entries_count(
	void			*obj,
	int			startoff)
{
	struct xfs_attr3_leafblock *leaf = obj;

	ASSERT(startoff == 0);
	if (be16_to_cpu(leaf->hdr.info.hdr.magic) != XFS_ATTR3_LEAF_MAGIC)
		return 0;
	return be16_to_cpu(leaf->hdr.count);
}

static int
attr_leaf_hdr_count(
	void			*obj,
	int			startoff)
{
	struct xfs_attr_leafblock *leaf = obj;

	ASSERT(startoff == 0);
	return be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC;
}

static int
attr3_leaf_hdr_count(
	void			*obj,
	int			startoff)
{
	struct xfs_attr3_leafblock *leaf = obj;

	ASSERT(startoff == 0);
	return be16_to_cpu(leaf->hdr.info.hdr.magic) == XFS_ATTR3_LEAF_MAGIC;
}

typedef int (*attr_leaf_entry_walk_f)(struct xfs_attr_leafblock *,
				      struct xfs_attr_leaf_entry *, int);
static int
attr_leaf_entry_walk(
	void				*obj,
	int				startoff,
	attr_leaf_entry_walk_f		func)
{
	struct xfs_attr_leafblock	*leaf = obj;
	struct xfs_attr3_icleaf_hdr	leafhdr;
	struct xfs_attr_leaf_entry	*entries;
	struct xfs_attr_leaf_entry	*e;
	int				i;
	int				off;

	ASSERT(bitoffs(startoff) == 0);
	if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC &&
	    be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR3_LEAF_MAGIC)
		return 0;

	off = byteize(startoff);
	xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);
	entries = xfs_attr3_leaf_entryp(leaf);

	for (i = 0; i < leafhdr.count; i++) {
		e = &entries[i];
		if (be16_to_cpu(e->nameidx) == off)
			return func(leaf, e, i);
	}
	return 0;
}

static int
__attr_leaf_name_local_count(
	struct xfs_attr_leafblock	*leaf,
	struct xfs_attr_leaf_entry      *e,
	int				i)
{
	return (e->flags & XFS_ATTR_LOCAL) != 0;
}

static int
attr_leaf_name_local_count(
	void			*obj,
	int			startoff)
{
	return attr_leaf_entry_walk(obj, startoff,
				    __attr_leaf_name_local_count);
}

static int
__attr_leaf_name_local_name_count(
	struct xfs_attr_leafblock	*leaf,
	struct xfs_attr_leaf_entry      *e,
	int				i)
{
	struct xfs_attr_leaf_name_local	*l;

	if (!(e->flags & XFS_ATTR_LOCAL))
		return 0;

	l = xfs_attr3_leaf_name_local(leaf, i);
	return l->namelen;
}

static int
attr_leaf_name_local_name_count(
	void				*obj,
	int				startoff)
{
	return attr_leaf_entry_walk(obj, startoff,
				    __attr_leaf_name_local_name_count);
}

static int
__attr_leaf_name_local_value_count(
	struct xfs_attr_leafblock	*leaf,
	struct xfs_attr_leaf_entry      *e,
	int				i)
{
	struct xfs_attr_leaf_name_local	*l;

	if (!(e->flags & XFS_ATTR_LOCAL))
		return 0;

	l = xfs_attr3_leaf_name_local(leaf, i);
	return be16_to_cpu(l->valuelen);
}

static int
attr_leaf_name_local_value_count(
	void				*obj,
	int				startoff)
{
	return attr_leaf_entry_walk(obj, startoff,
				    __attr_leaf_name_local_value_count);
}

static int
__attr_leaf_name_local_value_offset(
	struct xfs_attr_leafblock	*leaf,
	struct xfs_attr_leaf_entry      *e,
	int				i)
{
	struct xfs_attr_leaf_name_local	*l;
	char				*vp;

	l = xfs_attr3_leaf_name_local(leaf, i);
	vp = (char *)&l->nameval[l->namelen];

	return (int)bitize(vp - (char *)l);
}

static int
attr_leaf_name_local_value_offset(
	void				*obj,
	int				startoff,
	int				idx)
{
	return attr_leaf_entry_walk(obj, startoff,
				    __attr_leaf_name_local_value_offset);
}

static int
__attr_leaf_name_remote_count(
	struct xfs_attr_leafblock	*leaf,
	struct xfs_attr_leaf_entry      *e,
	int				i)
{
	return (e->flags & XFS_ATTR_LOCAL) == 0;
}

static int
attr_leaf_name_remote_count(
	void				*obj,
	int				startoff)
{
	return attr_leaf_entry_walk(obj, startoff,
				    __attr_leaf_name_remote_count);
}

static int
__attr_leaf_name_remote_name_count(
	struct xfs_attr_leafblock	*leaf,
	struct xfs_attr_leaf_entry      *e,
	int				i)
{
	struct xfs_attr_leaf_name_remote *r;

	if (e->flags & XFS_ATTR_LOCAL)
		return 0;

	r = xfs_attr3_leaf_name_remote(leaf, i);
	return r->namelen;
}

static int
attr_leaf_name_remote_name_count(
	void				*obj,
	int				startoff)
{
	return attr_leaf_entry_walk(obj, startoff,
				    __attr_leaf_name_remote_name_count);
}

int
attr_leaf_name_size(
	void				*obj,
	int				startoff,
	int				idx)
{
	struct xfs_attr_leafblock	*leaf = obj;
	struct xfs_attr_leaf_entry	*e;
	struct xfs_attr_leaf_name_local	*l;
	struct xfs_attr_leaf_name_remote *r;

	ASSERT(startoff == 0);
	if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC &&
	    be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR3_LEAF_MAGIC)
		return 0;
	e = &xfs_attr3_leaf_entryp(leaf)[idx];
	if (e->flags & XFS_ATTR_LOCAL) {
		l = xfs_attr3_leaf_name_local(leaf, idx);
		return (int)bitize(xfs_attr_leaf_entsize_local(l->namelen,
					be16_to_cpu(l->valuelen)));
	} else {
		r = xfs_attr3_leaf_name_remote(leaf, idx);
		return (int)bitize(xfs_attr_leaf_entsize_remote(r->namelen));
	}
}

static int
attr_leaf_nvlist_count(
	void			*obj,
	int			startoff)
{
	struct xfs_attr_leafblock *leaf = obj;

	ASSERT(startoff == 0);
	if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC)
		return 0;
	return be16_to_cpu(leaf->hdr.count);
}

static int
attr3_leaf_nvlist_count(
	void			*obj,
	int			startoff)
{
	struct xfs_attr3_leafblock *leaf = obj;

	ASSERT(startoff == 0);
	if (be16_to_cpu(leaf->hdr.info.hdr.magic) != XFS_ATTR3_LEAF_MAGIC)
		return 0;
	return be16_to_cpu(leaf->hdr.count);
}

static int
attr_leaf_nvlist_offset(
	void			*obj,
	int			startoff,
	int			idx)
{
	struct xfs_attr_leafblock *leaf = obj;
	struct xfs_attr_leaf_entry *e;

	ASSERT(startoff == 0);
	e = &xfs_attr3_leaf_entryp(leaf)[idx];
	return bitize(be16_to_cpu(e->nameidx));
}

static int
attr_node_btree_count(
	void			*obj,
	int			startoff)
{
	struct xfs_da_intnode	*node = obj;

	ASSERT(startoff == 0);		/* this is a base structure */
	if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC)
		return 0;
	return be16_to_cpu(node->hdr.__count);
}

static int
attr3_node_btree_count(
	void			*obj,
	int			startoff)
{
	struct xfs_da3_intnode	*node = obj;

	ASSERT(startoff == 0);
	if (be16_to_cpu(node->hdr.info.hdr.magic) != XFS_DA3_NODE_MAGIC)
		return 0;
	return be16_to_cpu(node->hdr.__count);
}


static int
attr_node_hdr_count(
	void			*obj,
	int			startoff)
{
	struct xfs_da_intnode	*node = obj;

	ASSERT(startoff == 0);
	return be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC;
}

static int
attr3_node_hdr_count(
	void			*obj,
	int			startoff)
{
	struct xfs_da3_intnode	*node = obj;

	ASSERT(startoff == 0);
	return be16_to_cpu(node->hdr.info.hdr.magic) == XFS_DA3_NODE_MAGIC;
}

int
attr_size(
	void	*obj,
	int	startoff,
	int	idx)
{
	return bitize(mp->m_sb.sb_blocksize);
}

/*
 * CRC enabled attribute block field definitions
 */
const field_t	attr3_hfld[] = {
	{ "", FLDT_ATTR3, OI(0), C1, 0, TYP_NONE },
	{ NULL }
};

#define	L3OFF(f)	bitize(offsetof(struct xfs_attr3_leafblock, f))
#define	N3OFF(f)	bitize(offsetof(struct xfs_da3_intnode, f))
const field_t	attr3_flds[] = {
	{ "hdr", FLDT_ATTR3_LEAF_HDR, OI(L3OFF(hdr)), attr3_leaf_hdr_count,
	  FLD_COUNT, TYP_NONE },
	{ "hdr", FLDT_DA3_NODE_HDR, OI(N3OFF(hdr)), attr3_node_hdr_count,
	  FLD_COUNT, TYP_NONE },
	{ "entries", FLDT_ATTR_LEAF_ENTRY, OI(L3OFF(entries)),
	  attr3_leaf_entries_count, FLD_ARRAY|FLD_COUNT, TYP_NONE },
	{ "btree", FLDT_ATTR_NODE_ENTRY, OI(N3OFF(__btree)),
	  attr3_node_btree_count, FLD_ARRAY|FLD_COUNT, TYP_NONE },
	{ "nvlist", FLDT_ATTR_LEAF_NAME, attr_leaf_nvlist_offset,
	  attr3_leaf_nvlist_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE },
	{ NULL }
};

#define	LH3OFF(f)	bitize(offsetof(struct xfs_attr3_leaf_hdr, f))
const field_t	attr3_leaf_hdr_flds[] = {
	{ "info", FLDT_DA3_BLKINFO, OI(LH3OFF(info)), C1, 0, TYP_NONE },
	{ "count", FLDT_UINT16D, OI(LH3OFF(count)), C1, 0, TYP_NONE },
	{ "usedbytes", FLDT_UINT16D, OI(LH3OFF(usedbytes)), C1, 0, TYP_NONE },
	{ "firstused", FLDT_UINT16D, OI(LH3OFF(firstused)), C1, 0, TYP_NONE },
	{ "holes", FLDT_UINT8D, OI(LH3OFF(holes)), C1, 0, TYP_NONE },
	{ "pad1", FLDT_UINT8X, OI(LH3OFF(pad1)), C1, FLD_SKIPALL, TYP_NONE },
	{ "freemap", FLDT_ATTR_LEAF_MAP, OI(LH3OFF(freemap)),
	  CI(XFS_ATTR_LEAF_MAPSIZE), FLD_ARRAY, TYP_NONE },
	{ NULL }
};

/*
 * Special read verifier for attribute buffers. Detect the magic number
 * appropriately and set the correct verifier and call it.
 */
static void
xfs_attr3_db_read_verify(
	struct xfs_buf		*bp)
{
	__be32			magic32;
	__be16			magic16;

	magic32 = *(__be32 *)bp->b_addr;
	magic16 = ((struct xfs_da_blkinfo *)bp->b_addr)->magic;

	switch (magic16) {
	case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
		bp->b_ops = &xfs_attr3_leaf_buf_ops;
		goto verify;
	case cpu_to_be16(XFS_DA3_NODE_MAGIC):
		bp->b_ops = &xfs_da3_node_buf_ops;
		goto verify;
	default:
		break;
	}

	switch (magic32) {
	case cpu_to_be32(XFS_ATTR3_RMT_MAGIC):
		bp->b_ops = &xfs_attr3_rmt_buf_ops;
		break;
	default:
		dbprintf(_("Unknown attribute buffer type!\n"));
		xfs_buf_ioerror(bp, -EFSCORRUPTED);
		return;
	}
verify:
	bp->b_ops->verify_read(bp);
}

static void
xfs_attr3_db_write_verify(
	struct xfs_buf		*bp)
{
	dbprintf(_("Writing unknown attribute buffer type!\n"));
	xfs_buf_ioerror(bp, -EFSCORRUPTED);
}

const struct xfs_buf_ops xfs_attr3_db_buf_ops = {
	.name = "xfs_attr3",
	.verify_read = xfs_attr3_db_read_verify,
	.verify_write = xfs_attr3_db_write_verify,
};
