/**
 * xattr.c
 *
 * Many parts of codes are copied from Linux kernel/fs/f2fs.
 *
 * Copyright (C) 2015 Huawei Ltd.
 * Witten by:
 *   Hou Pengyang <houpengyang@huawei.com>
 *   Liu Shuoran <liushuoran@huawei.com>
 *   Jaegeuk Kim <jaegeuk@kernel.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include "fsck.h"
#include "node.h"
#include "xattr.h"

void *read_all_xattrs(struct f2fs_sb_info *sbi, struct f2fs_node *inode)
{
	struct f2fs_xattr_header *header;
	void *txattr_addr;
	u64 inline_size = inline_xattr_size(&inode->i);

	txattr_addr = calloc(inline_size + BLOCK_SZ, 1);
	ASSERT(txattr_addr);

	if (inline_size)
		memcpy(txattr_addr, inline_xattr_addr(&inode->i), inline_size);

	/* Read from xattr node block. */
	if (inode->i.i_xattr_nid) {
		struct node_info ni;
		int ret;

		get_node_info(sbi, le32_to_cpu(inode->i.i_xattr_nid), &ni);
		ret = dev_read_block(txattr_addr + inline_size, ni.blk_addr);
		ASSERT(ret >= 0);
	}

	header = XATTR_HDR(txattr_addr);

	/* Never been allocated xattrs */
	if (le32_to_cpu(header->h_magic) != F2FS_XATTR_MAGIC) {
		header->h_magic = cpu_to_le32(F2FS_XATTR_MAGIC);
		header->h_refcount = cpu_to_le32(1);
	}
	return txattr_addr;
}

static struct f2fs_xattr_entry *__find_xattr(void *base_addr, int index,
		size_t len, const char *name)
{
	struct f2fs_xattr_entry *entry;
	list_for_each_xattr(entry, base_addr) {
		if (entry->e_name_index != index)
			continue;
		if (entry->e_name_len != len)
			continue;
		if (!memcmp(entry->e_name, name, len))
			break;
	}
	return entry;
}

static void write_all_xattrs(struct f2fs_sb_info *sbi,
		struct f2fs_node *inode, __u32 hsize, void *txattr_addr)
{
	void *xattr_addr;
	struct dnode_of_data dn;
	struct node_info ni;
	struct f2fs_node *xattr_node;
	nid_t new_nid = 0;
	block_t blkaddr;
	nid_t xnid = le32_to_cpu(inode->i.i_xattr_nid);
	u64 inline_size = inline_xattr_size(&inode->i);
	int ret;

	memcpy(inline_xattr_addr(&inode->i), txattr_addr, inline_size);

	if (hsize <= inline_size)
		return;

	if (!xnid) {
		f2fs_alloc_nid(sbi, &new_nid, 0);

		set_new_dnode(&dn, inode, NULL, new_nid);
		/* NAT entry would be updated by new_node_page. */
		blkaddr = new_node_block(sbi, &dn, XATTR_NODE_OFFSET);
		ASSERT(dn.node_blk);
		xattr_node = dn.node_blk;
		inode->i.i_xattr_nid = cpu_to_le32(new_nid);
	} else {
		set_new_dnode(&dn, inode, NULL, xnid);
		get_node_info(sbi, xnid, &ni);
		blkaddr = ni.blk_addr;
		xattr_node = calloc(BLOCK_SZ, 1);
		ASSERT(xattr_node);
		ret = dev_read_block(xattr_node, ni.blk_addr);
		ASSERT(ret >= 0);
	}

	/* write to xattr node block */
	xattr_addr = (void *)xattr_node;
	memcpy(xattr_addr, txattr_addr + inline_size,
			PAGE_SIZE - sizeof(struct node_footer));

	ret = dev_write_block(xattr_node, blkaddr);
	ASSERT(ret >= 0);
}

int f2fs_setxattr(struct f2fs_sb_info *sbi, nid_t ino, int index, const char *name,
		const void *value, size_t size, int flags)
{
	struct f2fs_node *inode;
	void *base_addr;
	struct f2fs_xattr_entry *here, *last;
	struct node_info ni;
	int error = 0;
	int len;
	int found, newsize;
	__u32 new_hsize;
	int ret;

	if (name == NULL)
		return -EINVAL;

	if (value == NULL)
		return -EINVAL;

	len = strlen(name);

	if (len > F2FS_NAME_LEN || size > MAX_VALUE_LEN)
		return -ERANGE;

	if (ino < 3)
		return -EINVAL;

	/* Now We just support selinux */
	ASSERT(index == F2FS_XATTR_INDEX_SECURITY);

	get_node_info(sbi, ino, &ni);
	inode = calloc(BLOCK_SZ, 1);
	ASSERT(inode);
	ret = dev_read_block(inode, ni.blk_addr);
	ASSERT(ret >= 0);

	base_addr = read_all_xattrs(sbi, inode);
	ASSERT(base_addr);

	here = __find_xattr(base_addr, index, len, name);

	found = IS_XATTR_LAST_ENTRY(here) ? 0 : 1;

	if ((flags & XATTR_REPLACE) && !found) {
		error = -ENODATA;
		goto exit;
	} else if ((flags & XATTR_CREATE) && found) {
		error = -EEXIST;
		goto exit;
	}

	last = here;
	while (!IS_XATTR_LAST_ENTRY(last))
		last = XATTR_NEXT_ENTRY(last);

	newsize = XATTR_ALIGN(sizeof(struct f2fs_xattr_entry) + len + size);

	/* 1. Check space */
	if (value) {
		int free;
		/*
		 * If value is NULL, it is remove operation.
		 * In case of update operation, we calculate free.
		 */
		free = MIN_OFFSET - ((char *)last - (char *)base_addr);
		if (found)
			free = free + ENTRY_SIZE(here);
		if (free < newsize) {
			error = -ENOSPC;
			goto exit;
		}
	}

	/* 2. Remove old entry */
	if (found) {
		/*
		 * If entry if sound, remove old entry.
		 * If not found, remove operation is not needed
		 */
		struct f2fs_xattr_entry *next = XATTR_NEXT_ENTRY(here);
		int oldsize = ENTRY_SIZE(here);

		memmove(here, next, (char *)last - (char *)next);
		last = (struct f2fs_xattr_entry *)((char *)last - oldsize);
		memset(last, 0, oldsize);

	}

	new_hsize = (char *)last - (char *)base_addr;

	/* 3. Write new entry */
	if (value) {
		char *pval;
		/*
		 * Before we come here, old entry is removed.
		 * We just write new entry.
		 */
		memset(last, 0, newsize);
		last->e_name_index = index;
		last->e_name_len = len;
		memcpy(last->e_name, name, len);
		pval = last->e_name + len;
		memcpy(pval, value, size);
		last->e_value_size = cpu_to_le16(size);
		new_hsize += newsize;
	}

	write_all_xattrs(sbi, inode, new_hsize, base_addr);

	/* inode need update */
	ret = dev_write_block(inode, ni.blk_addr);
	ASSERT(ret >= 0);
exit:
	free(base_addr);
	return error;
}

int inode_set_selinux(struct f2fs_sb_info *sbi, u32 ino, const char *secon)
{
	if (!secon)
		return 0;

	return f2fs_setxattr(sbi, ino, F2FS_XATTR_INDEX_SECURITY,
			XATTR_SELINUX_SUFFIX, secon, strlen(secon), 1);
}
