/*
 * linux/fs/hfsplus/attributes.c
 *
 * Vyacheslav Dubeyko <slava@dubeyko.com>
 *
 * Handling of records in attributes tree
 */

#include "hfsplus_fs.h"
#include "hfsplus_raw.h"

static struct kmem_cache *hfsplus_attr_tree_cachep;

int __init hfsplus_create_attr_tree_cache(void)
{
	if (hfsplus_attr_tree_cachep)
		return -EEXIST;

	hfsplus_attr_tree_cachep =
		kmem_cache_create("hfsplus_attr_cache",
			sizeof(hfsplus_attr_entry), 0,
			SLAB_HWCACHE_ALIGN, NULL);
	if (!hfsplus_attr_tree_cachep)
		return -ENOMEM;

	return 0;
}

void hfsplus_destroy_attr_tree_cache(void)
{
	kmem_cache_destroy(hfsplus_attr_tree_cachep);
}

int hfsplus_attr_bin_cmp_key(const hfsplus_btree_key *k1,
				const hfsplus_btree_key *k2)
{
	__be32 k1_cnid, k2_cnid;

	k1_cnid = k1->attr.cnid;
	k2_cnid = k2->attr.cnid;
	if (k1_cnid != k2_cnid)
		return be32_to_cpu(k1_cnid) < be32_to_cpu(k2_cnid) ? -1 : 1;

	return hfsplus_strcmp(
			(const struct hfsplus_unistr *)&k1->attr.key_name,
			(const struct hfsplus_unistr *)&k2->attr.key_name);
}

int hfsplus_attr_build_key(struct super_block *sb, hfsplus_btree_key *key,
			u32 cnid, const char *name)
{
	int len;

	memset(key, 0, sizeof(struct hfsplus_attr_key));
	key->attr.cnid = cpu_to_be32(cnid);
	if (name) {
		len = strlen(name);
		if (len > HFSPLUS_ATTR_MAX_STRLEN) {
			pr_err("invalid xattr name's length\n");
			return -EINVAL;
		}
		hfsplus_asc2uni(sb,
				(struct hfsplus_unistr *)&key->attr.key_name,
				HFSPLUS_ATTR_MAX_STRLEN, name, len);
		len = be16_to_cpu(key->attr.key_name.length);
	} else {
		key->attr.key_name.length = 0;
		len = 0;
	}

	/* The length of the key, as stored in key_len field, does not include
	 * the size of the key_len field itself.
	 * So, offsetof(hfsplus_attr_key, key_name) is a trick because
	 * it takes into consideration key_len field (__be16) of
	 * hfsplus_attr_key structure instead of length field (__be16) of
	 * hfsplus_attr_unistr structure.
	 */
	key->key_len =
		cpu_to_be16(offsetof(struct hfsplus_attr_key, key_name) +
				2 * len);

	return 0;
}

void hfsplus_attr_build_key_uni(hfsplus_btree_key *key,
					u32 cnid,
					struct hfsplus_attr_unistr *name)
{
	int ustrlen;

	memset(key, 0, sizeof(struct hfsplus_attr_key));
	ustrlen = be16_to_cpu(name->length);
	key->attr.cnid = cpu_to_be32(cnid);
	key->attr.key_name.length = cpu_to_be16(ustrlen);
	ustrlen *= 2;
	memcpy(key->attr.key_name.unicode, name->unicode, ustrlen);

	/* The length of the key, as stored in key_len field, does not include
	 * the size of the key_len field itself.
	 * So, offsetof(hfsplus_attr_key, key_name) is a trick because
	 * it takes into consideration key_len field (__be16) of
	 * hfsplus_attr_key structure instead of length field (__be16) of
	 * hfsplus_attr_unistr structure.
	 */
	key->key_len =
		cpu_to_be16(offsetof(struct hfsplus_attr_key, key_name) +
				ustrlen);
}

hfsplus_attr_entry *hfsplus_alloc_attr_entry(void)
{
	return kmem_cache_alloc(hfsplus_attr_tree_cachep, GFP_KERNEL);
}

void hfsplus_destroy_attr_entry(hfsplus_attr_entry *entry)
{
	if (entry)
		kmem_cache_free(hfsplus_attr_tree_cachep, entry);
}

#define HFSPLUS_INVALID_ATTR_RECORD -1

static int hfsplus_attr_build_record(hfsplus_attr_entry *entry, int record_type,
				u32 cnid, const void *value, size_t size)
{
	if (record_type == HFSPLUS_ATTR_FORK_DATA) {
		/*
		 * Mac OS X supports only inline data attributes.
		 * Do nothing
		 */
		memset(entry, 0, sizeof(*entry));
		return sizeof(struct hfsplus_attr_fork_data);
	} else if (record_type == HFSPLUS_ATTR_EXTENTS) {
		/*
		 * Mac OS X supports only inline data attributes.
		 * Do nothing.
		 */
		memset(entry, 0, sizeof(*entry));
		return sizeof(struct hfsplus_attr_extents);
	} else if (record_type == HFSPLUS_ATTR_INLINE_DATA) {
		u16 len;

		memset(entry, 0, sizeof(struct hfsplus_attr_inline_data));
		entry->inline_data.record_type = cpu_to_be32(record_type);
		if (size <= HFSPLUS_MAX_INLINE_DATA_SIZE)
			len = size;
		else
			return HFSPLUS_INVALID_ATTR_RECORD;
		entry->inline_data.length = cpu_to_be16(len);
		memcpy(entry->inline_data.raw_bytes, value, len);
		/*
		 * Align len on two-byte boundary.
		 * It needs to add pad byte if we have odd len.
		 */
		len = round_up(len, 2);
		return offsetof(struct hfsplus_attr_inline_data, raw_bytes) +
					len;
	} else /* invalid input */
		memset(entry, 0, sizeof(*entry));

	return HFSPLUS_INVALID_ATTR_RECORD;
}

int hfsplus_find_attr(struct super_block *sb, u32 cnid,
			const char *name, struct hfs_find_data *fd)
{
	int err = 0;

	hfs_dbg(ATTR_MOD, "find_attr: %s,%d\n", name ? name : NULL, cnid);

	if (!HFSPLUS_SB(sb)->attr_tree) {
		pr_err("attributes file doesn't exist\n");
		return -EINVAL;
	}

	if (name) {
		err = hfsplus_attr_build_key(sb, fd->search_key, cnid, name);
		if (err)
			goto failed_find_attr;
		err = hfs_brec_find(fd, hfs_find_rec_by_key);
		if (err)
			goto failed_find_attr;
	} else {
		err = hfsplus_attr_build_key(sb, fd->search_key, cnid, NULL);
		if (err)
			goto failed_find_attr;
		err = hfs_brec_find(fd, hfs_find_1st_rec_by_cnid);
		if (err)
			goto failed_find_attr;
	}

failed_find_attr:
	return err;
}

int hfsplus_attr_exists(struct inode *inode, const char *name)
{
	int err = 0;
	struct super_block *sb = inode->i_sb;
	struct hfs_find_data fd;

	if (!HFSPLUS_SB(sb)->attr_tree)
		return 0;

	err = hfs_find_init(HFSPLUS_SB(sb)->attr_tree, &fd);
	if (err)
		return 0;

	err = hfsplus_find_attr(sb, inode->i_ino, name, &fd);
	if (err)
		goto attr_not_found;

	hfs_find_exit(&fd);
	return 1;

attr_not_found:
	hfs_find_exit(&fd);
	return 0;
}

int hfsplus_create_attr(struct inode *inode,
				const char *name,
				const void *value, size_t size)
{
	struct super_block *sb = inode->i_sb;
	struct hfs_find_data fd;
	hfsplus_attr_entry *entry_ptr;
	int entry_size;
	int err;

	hfs_dbg(ATTR_MOD, "create_attr: %s,%ld\n",
		name ? name : NULL, inode->i_ino);

	if (!HFSPLUS_SB(sb)->attr_tree) {
		pr_err("attributes file doesn't exist\n");
		return -EINVAL;
	}

	entry_ptr = hfsplus_alloc_attr_entry();
	if (!entry_ptr)
		return -ENOMEM;

	err = hfs_find_init(HFSPLUS_SB(sb)->attr_tree, &fd);
	if (err)
		goto failed_init_create_attr;

	if (name) {
		err = hfsplus_attr_build_key(sb, fd.search_key,
						inode->i_ino, name);
		if (err)
			goto failed_create_attr;
	} else {
		err = -EINVAL;
		goto failed_create_attr;
	}

	/* Mac OS X supports only inline data attributes. */
	entry_size = hfsplus_attr_build_record(entry_ptr,
					HFSPLUS_ATTR_INLINE_DATA,
					inode->i_ino,
					value, size);
	if (entry_size == HFSPLUS_INVALID_ATTR_RECORD) {
		err = -EINVAL;
		goto failed_create_attr;
	}

	err = hfs_brec_find(&fd, hfs_find_rec_by_key);
	if (err != -ENOENT) {
		if (!err)
			err = -EEXIST;
		goto failed_create_attr;
	}

	err = hfs_brec_insert(&fd, entry_ptr, entry_size);
	if (err)
		goto failed_create_attr;

	hfsplus_mark_inode_dirty(inode, HFSPLUS_I_ATTR_DIRTY);

failed_create_attr:
	hfs_find_exit(&fd);

failed_init_create_attr:
	hfsplus_destroy_attr_entry(entry_ptr);
	return err;
}

static int __hfsplus_delete_attr(struct inode *inode, u32 cnid,
					struct hfs_find_data *fd)
{
	int err = 0;
	__be32 found_cnid, record_type;

	hfs_bnode_read(fd->bnode, &found_cnid,
			fd->keyoffset +
			offsetof(struct hfsplus_attr_key, cnid),
			sizeof(__be32));
	if (cnid != be32_to_cpu(found_cnid))
		return -ENOENT;

	hfs_bnode_read(fd->bnode, &record_type,
			fd->entryoffset, sizeof(record_type));

	switch (be32_to_cpu(record_type)) {
	case HFSPLUS_ATTR_INLINE_DATA:
		/* All is OK. Do nothing. */
		break;
	case HFSPLUS_ATTR_FORK_DATA:
	case HFSPLUS_ATTR_EXTENTS:
		pr_err("only inline data xattr are supported\n");
		return -EOPNOTSUPP;
	default:
		pr_err("invalid extended attribute record\n");
		return -ENOENT;
	}

	err = hfs_brec_remove(fd);
	if (err)
		return err;

	hfsplus_mark_inode_dirty(inode, HFSPLUS_I_ATTR_DIRTY);
	return err;
}

int hfsplus_delete_attr(struct inode *inode, const char *name)
{
	int err = 0;
	struct super_block *sb = inode->i_sb;
	struct hfs_find_data fd;

	hfs_dbg(ATTR_MOD, "delete_attr: %s,%ld\n",
		name ? name : NULL, inode->i_ino);

	if (!HFSPLUS_SB(sb)->attr_tree) {
		pr_err("attributes file doesn't exist\n");
		return -EINVAL;
	}

	err = hfs_find_init(HFSPLUS_SB(sb)->attr_tree, &fd);
	if (err)
		return err;

	if (name) {
		err = hfsplus_attr_build_key(sb, fd.search_key,
						inode->i_ino, name);
		if (err)
			goto out;
	} else {
		pr_err("invalid extended attribute name\n");
		err = -EINVAL;
		goto out;
	}

	err = hfs_brec_find(&fd, hfs_find_rec_by_key);
	if (err)
		goto out;

	err = __hfsplus_delete_attr(inode, inode->i_ino, &fd);
	if (err)
		goto out;

out:
	hfs_find_exit(&fd);
	return err;
}

int hfsplus_delete_all_attrs(struct inode *dir, u32 cnid)
{
	int err = 0;
	struct hfs_find_data fd;

	hfs_dbg(ATTR_MOD, "delete_all_attrs: %d\n", cnid);

	if (!HFSPLUS_SB(dir->i_sb)->attr_tree) {
		pr_err("attributes file doesn't exist\n");
		return -EINVAL;
	}

	err = hfs_find_init(HFSPLUS_SB(dir->i_sb)->attr_tree, &fd);
	if (err)
		return err;

	for (;;) {
		err = hfsplus_find_attr(dir->i_sb, cnid, NULL, &fd);
		if (err) {
			if (err != -ENOENT)
				pr_err("xattr search failed\n");
			goto end_delete_all;
		}

		err = __hfsplus_delete_attr(dir, cnid, &fd);
		if (err)
			goto end_delete_all;
	}

end_delete_all:
	hfs_find_exit(&fd);
	return err;
}
