/*
 * Copyright (C) 2007 Red Hat.  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 v2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will 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 to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 021110-1307, USA.
 */

#include <linux/init.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/rwsem.h>
#include <linux/xattr.h>
#include "ctree.h"
#include "btrfs_inode.h"
#include "transaction.h"
#include "xattr.h"
#include "disk-io.h"
static struct xattr_handler *btrfs_xattr_handler_map[] = {
	[BTRFS_XATTR_INDEX_USER]		= &btrfs_xattr_user_handler,
#ifdef CONFIG_FS_POSIX_ACL
//	[BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS]	= &btrfs_xattr_acl_access_handler,
//	[BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT]	= &btrfs_xattr_acl_default_handler,
#endif
	[BTRFS_XATTR_INDEX_TRUSTED]		= &btrfs_xattr_trusted_handler,
	[BTRFS_XATTR_INDEX_SECURITY]		= &btrfs_xattr_security_handler,
//	[BTRFS_XATTR_INDEX_SYSTEM]		= &btrfs_xattr_system_handler,
};
struct xattr_handler *btrfs_xattr_handlers[] = {
	&btrfs_xattr_user_handler,
#ifdef CONFIG_FS_POSIX_ACL
//	&btrfs_xattr_acl_access_handler,
//	&btrfs_xattr_acl_default_handler,
#endif
	&btrfs_xattr_trusted_handler,
	&btrfs_xattr_security_handler,
//	&btrfs_xattr_system_handler,
	NULL,
};

/*
 * @param name - the xattr name
 * @return - the xattr_handler for the xattr, NULL if its not found
 *
 * use this with listxattr where we don't already know the type of xattr we
 * have
 */
static struct xattr_handler *find_btrfs_xattr_handler(struct extent_buffer *l,
						      unsigned long name_ptr,
						      u16 name_len)
{
	struct xattr_handler *handler = NULL;
	int i = 0;

	for (handler = btrfs_xattr_handlers[i]; handler != NULL; i++,
	     handler = btrfs_xattr_handlers[i]) {
		u16 prefix_len = strlen(handler->prefix);

		if (name_len < prefix_len)
			continue;

		if (memcmp_extent_buffer(l, handler->prefix, name_ptr,
					 prefix_len) == 0)
			break;
	}

	return handler;
}

/*
 * @param name_index - the index for the xattr handler
 * @return the xattr_handler if we found it, NULL otherwise
 *
 * use this if we know the type of the xattr already
 */
static struct xattr_handler *btrfs_xattr_handler(int name_index)
{
	struct xattr_handler *handler = NULL;

	if (name_index >= 0 &&
	    name_index < ARRAY_SIZE(btrfs_xattr_handler_map))
		handler = btrfs_xattr_handler_map[name_index];

	return handler;
}

static inline char *get_name(const char *name, int name_index)
{
	char *ret = NULL;
	struct xattr_handler *handler = btrfs_xattr_handler(name_index);
	int prefix_len;

	if (!handler)
		return ret;

	prefix_len = strlen(handler->prefix);

	ret = kmalloc(strlen(name) + prefix_len + 1, GFP_KERNEL);
	if (!ret)
		return ret;

	memcpy(ret, handler->prefix, prefix_len);
	memcpy(ret+prefix_len, name, strlen(name));
	ret[prefix_len + strlen(name)] = '\0';

	return ret;
}

size_t btrfs_xattr_generic_list(struct inode *inode, char *list,
				size_t list_size, const char *name,
				size_t name_len)
{
	if (list && (name_len+1) <= list_size) {
		memcpy(list, name, name_len);
		list[name_len] = '\0';
	} else
		return -ERANGE;

	return name_len+1;
}

ssize_t btrfs_xattr_get(struct inode *inode, int name_index,
			const char *attr_name, void *buffer, size_t size)
{
	struct btrfs_dir_item *di;
	struct btrfs_root *root = BTRFS_I(inode)->root;
	struct btrfs_path *path;
	struct extent_buffer *leaf;
	struct xattr_handler *handler = btrfs_xattr_handler(name_index);
	int ret = 0;
	unsigned long data_ptr;
	char *name;

	if (!handler)
		return -EOPNOTSUPP;
	name = get_name(attr_name, name_index);
	if (!name)
		return -ENOMEM;

	path = btrfs_alloc_path();
	if (!path) {
		kfree(name);
		return -ENOMEM;
	}

	/* lookup the xattr by name */
	di = btrfs_lookup_xattr(NULL, root, path, inode->i_ino, name,
				strlen(name), 0);
	if (!di || IS_ERR(di)) {
		ret = -ENODATA;
		goto out;
	}

	leaf = path->nodes[0];
	/* if size is 0, that means we want the size of the attr */
	if (!size) {
		ret = btrfs_dir_data_len(leaf, di);
		goto out;
	}

	/* now get the data out of our dir_item */
	if (btrfs_dir_data_len(leaf, di) > size) {
		ret = -ERANGE;
		goto out;
	}
	data_ptr = (unsigned long)((char *)(di + 1) +
				   btrfs_dir_name_len(leaf, di));
	read_extent_buffer(leaf, buffer, data_ptr,
			   btrfs_dir_data_len(leaf, di));
	ret = btrfs_dir_data_len(leaf, di);

out:
	kfree(name);
	btrfs_free_path(path);
	return ret;
}

int btrfs_xattr_set(struct inode *inode, int name_index,
		    const char *attr_name, const void *value, size_t size,
		    int flags)
{
	struct btrfs_dir_item *di;
	struct btrfs_root *root = BTRFS_I(inode)->root;
	struct btrfs_trans_handle *trans;
	struct btrfs_path *path;
	struct xattr_handler *handler = btrfs_xattr_handler(name_index);
	char *name;
	int ret = 0, mod = 0;
	if (!handler)
		return -EOPNOTSUPP;
	name = get_name(attr_name, name_index);
	if (!name)
		return -ENOMEM;

	path = btrfs_alloc_path();
	if (!path) {
		kfree(name);
		return -ENOMEM;
	}

	trans = btrfs_start_transaction(root, 1);
	btrfs_set_trans_block_group(trans, inode);

	/* first lets see if we already have this xattr */
	di = btrfs_lookup_xattr(trans, root, path, inode->i_ino, name,
				strlen(name), -1);
	if (IS_ERR(di)) {
		ret = PTR_ERR(di);
		goto out;
	}

	/* ok we already have this xattr, lets remove it */
	if (di) {
		/* if we want create only exit */
		if (flags & XATTR_CREATE) {
			ret = -EEXIST;
			goto out;
		}

		ret = btrfs_delete_one_dir_name(trans, root, path, di);
		if (ret)
			goto out;
		btrfs_release_path(root, path);

		/* if we don't have a value then we are removing the xattr */
		if (!value) {
			mod = 1;
			goto out;
		}
	} else if (flags & XATTR_REPLACE) {
		/* we couldn't find the attr to replace, so error out */
		ret = -ENODATA;
		goto out;
	}

	/* ok we have to create a completely new xattr */
	ret = btrfs_insert_xattr_item(trans, root, name, strlen(name),
				      value, size, inode->i_ino);
	if (ret)
		goto out;
	mod = 1;

out:
	if (mod) {
		inode->i_ctime = CURRENT_TIME;
		ret = btrfs_update_inode(trans, root, inode);
	}

	btrfs_end_transaction(trans, root);
	kfree(name);
	btrfs_free_path(path);

	return ret;
}

ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
{
	struct btrfs_key key, found_key;
	struct inode *inode = dentry->d_inode;
	struct btrfs_root *root = BTRFS_I(inode)->root;
	struct btrfs_path *path;
	struct btrfs_item *item;
	struct extent_buffer *leaf;
	struct btrfs_dir_item *di;
	struct xattr_handler *handler;
	int ret = 0, slot, advance;
	size_t total_size = 0, size_left = size, written;
	unsigned long name_ptr;
	char *name;
	u32 nritems;

	/*
	 * ok we want all objects associated with this id.
	 * NOTE: we set key.offset = 0; because we want to start with the
	 * first xattr that we find and walk forward
	 */
	key.objectid = inode->i_ino;
	btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY);
	key.offset = 0;

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;
	path->reada = 2;

	/* search for our xattrs */
	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
	if (ret < 0)
		goto err;
	ret = 0;
	advance = 0;
	while (1) {
		leaf = path->nodes[0];
		nritems = btrfs_header_nritems(leaf);
		slot = path->slots[0];

		/* this is where we start walking through the path */
		if (advance || slot >= nritems) {
			/*
			 * if we've reached the last slot in this leaf we need
			 * to go to the next leaf and reset everything
			 */
			if (slot >= nritems-1) {
				ret = btrfs_next_leaf(root, path);
				if (ret)
					break;
				leaf = path->nodes[0];
				nritems = btrfs_header_nritems(leaf);
				slot = path->slots[0];
			} else {
				/*
				 * just walking through the slots on this leaf
				 */
				slot++;
				path->slots[0]++;
			}
		}
		advance = 1;

		item = btrfs_item_nr(leaf, slot);
		btrfs_item_key_to_cpu(leaf, &found_key, slot);

		/* check to make sure this item is what we want */
		if (found_key.objectid != key.objectid)
			break;
		if (btrfs_key_type(&found_key) != BTRFS_XATTR_ITEM_KEY)
			break;

		di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);

		total_size += btrfs_dir_name_len(leaf, di)+1;

		/* we are just looking for how big our buffer needs to be */
		if (!size)
			continue;

		/* find our handler for this xattr */
		name_ptr = (unsigned long)(di + 1);
		handler = find_btrfs_xattr_handler(leaf, name_ptr,
						   btrfs_dir_name_len(leaf, di));
		if (!handler) {
			printk(KERN_ERR "btrfs: unsupported xattr found\n");
			continue;
		}

		name = kmalloc(btrfs_dir_name_len(leaf, di), GFP_KERNEL);
		read_extent_buffer(leaf, name, name_ptr,
				   btrfs_dir_name_len(leaf, di));

		/* call the list function associated with this xattr */
		written = handler->list(inode, buffer, size_left, name,
					btrfs_dir_name_len(leaf, di));
		kfree(name);

		if (written < 0) {
			ret = -ERANGE;
			break;
		}

		size_left -= written;
		buffer += written;
	}
	ret = total_size;

err:
	btrfs_free_path(path);

	return ret;
}

/*
 * delete all the xattrs associated with the inode.
 */
int btrfs_delete_xattrs(struct btrfs_trans_handle *trans,
			struct btrfs_root *root, struct inode *inode)
{
	struct btrfs_path *path;
	struct btrfs_key key, found_key;
	struct btrfs_item *item;
	struct extent_buffer *leaf;
	int ret;

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;
	path->reada = -1;
	key.objectid = inode->i_ino;
	btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY);
	key.offset = (u64)-1;

	while(1) {
		/* look for our next xattr */
		ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
		if (ret < 0)
			goto out;
		BUG_ON(ret == 0);

		if (path->slots[0] == 0)
			break;

		path->slots[0]--;
		leaf = path->nodes[0];
		item = btrfs_item_nr(leaf, path->slots[0]);
		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);

		if (found_key.objectid != key.objectid)
			break;
		if (btrfs_key_type(&found_key) != BTRFS_XATTR_ITEM_KEY)
			break;

		ret = btrfs_del_item(trans, root, path);
		BUG_ON(ret);
		btrfs_release_path(root, path);
	}
	ret = 0;
out:
	btrfs_free_path(path);

	return ret;
}

/*
 * Handler functions
 */
#define BTRFS_XATTR_SETGET_FUNCS(name, index)				\
static int btrfs_xattr_##name##_get(struct inode *inode,		\
				    const char *name, void *value,	\
				    size_t size)			\
{									\
	if (*name == '\0')						\
		return -EINVAL;						\
	return btrfs_xattr_get(inode, index, name, value, size);	\
}									\
static int btrfs_xattr_##name##_set(struct inode *inode,		\
				    const char *name, const void *value,\
				    size_t size, int flags)		\
{									\
	if (*name == '\0')						\
		return -EINVAL;						\
	return btrfs_xattr_set(inode, index, name, value, size, flags);	\
}

BTRFS_XATTR_SETGET_FUNCS(security, BTRFS_XATTR_INDEX_SECURITY);
BTRFS_XATTR_SETGET_FUNCS(system, BTRFS_XATTR_INDEX_SYSTEM);
BTRFS_XATTR_SETGET_FUNCS(user, BTRFS_XATTR_INDEX_USER);
BTRFS_XATTR_SETGET_FUNCS(trusted, BTRFS_XATTR_INDEX_TRUSTED);

struct xattr_handler btrfs_xattr_security_handler = {
	.prefix = XATTR_SECURITY_PREFIX,
	.list	= btrfs_xattr_generic_list,
	.get	= btrfs_xattr_security_get,
	.set	= btrfs_xattr_security_set,
};

struct xattr_handler btrfs_xattr_system_handler = {
	.prefix = XATTR_SYSTEM_PREFIX,
	.list	= btrfs_xattr_generic_list,
	.get	= btrfs_xattr_system_get,
	.set	= btrfs_xattr_system_set,
};

struct xattr_handler btrfs_xattr_user_handler = {
	.prefix	= XATTR_USER_PREFIX,
	.list	= btrfs_xattr_generic_list,
	.get	= btrfs_xattr_user_get,
	.set	= btrfs_xattr_user_set,
};

struct xattr_handler btrfs_xattr_trusted_handler = {
	.prefix = XATTR_TRUSTED_PREFIX,
	.list	= btrfs_xattr_generic_list,
	.get	= btrfs_xattr_trusted_get,
	.set	= btrfs_xattr_trusted_set,
};
