// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright (c) 2015, Linaro Limited
 */

#include <assert.h>
#include <kernel/mutex.h>
#include <kernel/panic.h>
#include <kernel/thread.h>
#include <mempool.h>
#include <mm/core_memprot.h>
#include <mm/tee_pager.h>
#include <optee_rpc_cmd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string_ext.h>
#include <string.h>
#include <sys/queue.h>
#include <tee/fs_dirfile.h>
#include <tee/fs_htree.h>
#include <tee/tee_fs.h>
#include <tee/tee_fs_rpc.h>
#include <tee/tee_pobj.h>
#include <trace.h>
#include <utee_defines.h>
#include <util.h>

#define BLOCK_SHIFT	12

#define BLOCK_SIZE	(1 << BLOCK_SHIFT)

struct tee_fs_fd {
	struct tee_fs_htree *ht;
	int fd;
	struct tee_fs_dirfile_fileh dfh;
	const TEE_UUID *uuid;
};

struct tee_fs_dir {
	struct tee_fs_dirfile_dirh *dirh;
	int idx;
	struct tee_fs_dirent d;
	const TEE_UUID *uuid;
};

static int pos_to_block_num(int position)
{
	return position >> BLOCK_SHIFT;
}

static struct mutex ree_fs_mutex = MUTEX_INITIALIZER;

static void *get_tmp_block(void)
{
	return mempool_alloc(mempool_default, BLOCK_SIZE);
}

static void put_tmp_block(void *tmp_block)
{
	mempool_free(mempool_default, tmp_block);
}

static TEE_Result out_of_place_write(struct tee_fs_fd *fdp, size_t pos,
				     const void *buf, size_t len)
{
	TEE_Result res;
	size_t start_block_num = pos_to_block_num(pos);
	size_t end_block_num = pos_to_block_num(pos + len - 1);
	size_t remain_bytes = len;
	uint8_t *data_ptr = (uint8_t *)buf;
	uint8_t *block;
	struct tee_fs_htree_meta *meta = tee_fs_htree_get_meta(fdp->ht);

	/*
	 * It doesn't make sense to call this function if nothing is to be
	 * written. This also guards against end_block_num getting an
	 * unexpected value when pos == 0 and len == 0.
	 */
	if (!len)
		return TEE_ERROR_BAD_PARAMETERS;

	block = get_tmp_block();
	if (!block)
		return TEE_ERROR_OUT_OF_MEMORY;

	while (start_block_num <= end_block_num) {
		size_t offset = pos % BLOCK_SIZE;
		size_t size_to_write = MIN(remain_bytes, (size_t)BLOCK_SIZE);

		if (size_to_write + offset > BLOCK_SIZE)
			size_to_write = BLOCK_SIZE - offset;

		if (start_block_num * BLOCK_SIZE <
		    ROUNDUP(meta->length, BLOCK_SIZE)) {
			res = tee_fs_htree_read_block(&fdp->ht,
						      start_block_num, block);
			if (res != TEE_SUCCESS)
				goto exit;
		} else {
			memset(block, 0, BLOCK_SIZE);
		}

		if (data_ptr)
			memcpy(block + offset, data_ptr, size_to_write);
		else
			memset(block + offset, 0, size_to_write);

		res = tee_fs_htree_write_block(&fdp->ht, start_block_num,
					       block);
		if (res != TEE_SUCCESS)
			goto exit;

		if (data_ptr)
			data_ptr += size_to_write;
		remain_bytes -= size_to_write;
		start_block_num++;
		pos += size_to_write;
	}

	if (pos > meta->length) {
		meta->length = pos;
		tee_fs_htree_meta_set_dirty(fdp->ht);
	}

exit:
	if (block)
		put_tmp_block(block);
	return res;
}

static TEE_Result get_offs_size(enum tee_fs_htree_type type, size_t idx,
				uint8_t vers, size_t *offs, size_t *size)
{
	const size_t node_size = sizeof(struct tee_fs_htree_node_image);
	const size_t block_nodes = BLOCK_SIZE / (node_size * 2);
	size_t pbn;
	size_t bidx;

	assert(vers == 0 || vers == 1);

	/*
	 * File layout
	 * [demo with input:
	 * BLOCK_SIZE = 4096,
	 * node_size = 66,
	 * block_nodes = 4096/(66*2) = 31 ]
	 *
	 * phys block 0:
	 * tee_fs_htree_image vers 0 @ offs = 0
	 * tee_fs_htree_image vers 1 @ offs = sizeof(tee_fs_htree_image)
	 *
	 * phys block 1:
	 * tee_fs_htree_node_image 0  vers 0 @ offs = 0
	 * tee_fs_htree_node_image 0  vers 1 @ offs = node_size
	 * tee_fs_htree_node_image 1  vers 0 @ offs = node_size * 2
	 * tee_fs_htree_node_image 1  vers 1 @ offs = node_size * 3
	 * ...
	 * tee_fs_htree_node_image 30 vers 0 @ offs = node_size * 60
	 * tee_fs_htree_node_image 30 vers 1 @ offs = node_size * 61
	 *
	 * phys block 2:
	 * data block 0 vers 0
	 *
	 * phys block 3:
	 * data block 0 vers 1
	 *
	 * ...
	 * phys block 62:
	 * data block 30 vers 0
	 *
	 * phys block 63:
	 * data block 30 vers 1
	 *
	 * phys block 64:
	 * tee_fs_htree_node_image 31  vers 0 @ offs = 0
	 * tee_fs_htree_node_image 31  vers 1 @ offs = node_size
	 * tee_fs_htree_node_image 32  vers 0 @ offs = node_size * 2
	 * tee_fs_htree_node_image 32  vers 1 @ offs = node_size * 3
	 * ...
	 * tee_fs_htree_node_image 61 vers 0 @ offs = node_size * 60
	 * tee_fs_htree_node_image 61 vers 1 @ offs = node_size * 61
	 *
	 * phys block 65:
	 * data block 31 vers 0
	 *
	 * phys block 66:
	 * data block 31 vers 1
	 * ...
	 */

	switch (type) {
	case TEE_FS_HTREE_TYPE_HEAD:
		*offs = sizeof(struct tee_fs_htree_image) * vers;
		*size = sizeof(struct tee_fs_htree_image);
		return TEE_SUCCESS;
	case TEE_FS_HTREE_TYPE_NODE:
		pbn = 1 + ((idx / block_nodes) * block_nodes * 2);
		*offs = pbn * BLOCK_SIZE +
			2 * node_size * (idx % block_nodes) +
			node_size * vers;
		*size = node_size;
		return TEE_SUCCESS;
	case TEE_FS_HTREE_TYPE_BLOCK:
		bidx = 2 * idx + vers;
		pbn = 2 + bidx + bidx / (block_nodes * 2 - 1);
		*offs = pbn * BLOCK_SIZE;
		*size = BLOCK_SIZE;
		return TEE_SUCCESS;
	default:
		return TEE_ERROR_GENERIC;
	}
}

static TEE_Result ree_fs_rpc_read_init(void *aux,
				       struct tee_fs_rpc_operation *op,
				       enum tee_fs_htree_type type, size_t idx,
				       uint8_t vers, void **data)
{
	struct tee_fs_fd *fdp = aux;
	TEE_Result res;
	size_t offs;
	size_t size;

	res = get_offs_size(type, idx, vers, &offs, &size);
	if (res != TEE_SUCCESS)
		return res;

	return tee_fs_rpc_read_init(op, OPTEE_RPC_CMD_FS, fdp->fd,
				    offs, size, data);
}

static TEE_Result ree_fs_rpc_write_init(void *aux,
					struct tee_fs_rpc_operation *op,
					enum tee_fs_htree_type type, size_t idx,
					uint8_t vers, void **data)
{
	struct tee_fs_fd *fdp = aux;
	TEE_Result res;
	size_t offs;
	size_t size;

	res = get_offs_size(type, idx, vers, &offs, &size);
	if (res != TEE_SUCCESS)
		return res;

	return tee_fs_rpc_write_init(op, OPTEE_RPC_CMD_FS, fdp->fd,
				     offs, size, data);
}

static const struct tee_fs_htree_storage ree_fs_storage_ops = {
	.block_size = BLOCK_SIZE,
	.rpc_read_init = ree_fs_rpc_read_init,
	.rpc_read_final = tee_fs_rpc_read_final,
	.rpc_write_init = ree_fs_rpc_write_init,
	.rpc_write_final = tee_fs_rpc_write_final,
};

static TEE_Result ree_fs_ftruncate_internal(struct tee_fs_fd *fdp,
					    tee_fs_off_t new_file_len)
{
	TEE_Result res;
	struct tee_fs_htree_meta *meta = tee_fs_htree_get_meta(fdp->ht);

	if ((size_t)new_file_len > meta->length) {
		size_t ext_len = new_file_len - meta->length;

		res = out_of_place_write(fdp, meta->length, NULL, ext_len);
		if (res != TEE_SUCCESS)
			return res;
	} else {
		size_t offs;
		size_t sz;

		res = get_offs_size(TEE_FS_HTREE_TYPE_BLOCK,
				    ROUNDUP(new_file_len, BLOCK_SIZE) /
					BLOCK_SIZE, 1, &offs, &sz);
		if (res != TEE_SUCCESS)
			return res;

		res = tee_fs_htree_truncate(&fdp->ht,
					    new_file_len / BLOCK_SIZE);
		if (res != TEE_SUCCESS)
			return res;

		res = tee_fs_rpc_truncate(OPTEE_RPC_CMD_FS, fdp->fd,
					  offs + sz);
		if (res != TEE_SUCCESS)
			return res;

		meta->length = new_file_len;
		tee_fs_htree_meta_set_dirty(fdp->ht);
	}

	return TEE_SUCCESS;
}

static TEE_Result ree_fs_read_primitive(struct tee_file_handle *fh, size_t pos,
					void *buf, size_t *len)
{
	TEE_Result res;
	int start_block_num;
	int end_block_num;
	size_t remain_bytes;
	uint8_t *data_ptr = buf;
	uint8_t *block = NULL;
	struct tee_fs_fd *fdp = (struct tee_fs_fd *)fh;
	struct tee_fs_htree_meta *meta = tee_fs_htree_get_meta(fdp->ht);

	remain_bytes = *len;
	if ((pos + remain_bytes) < remain_bytes || pos > meta->length)
		remain_bytes = 0;
	else if (pos + remain_bytes > meta->length)
		remain_bytes = meta->length - pos;

	*len = remain_bytes;

	if (!remain_bytes) {
		res = TEE_SUCCESS;
		goto exit;
	}

	start_block_num = pos_to_block_num(pos);
	end_block_num = pos_to_block_num(pos + remain_bytes - 1);

	block = get_tmp_block();
	if (!block) {
		res = TEE_ERROR_OUT_OF_MEMORY;
		goto exit;
	}

	while (start_block_num <= end_block_num) {
		size_t offset = pos % BLOCK_SIZE;
		size_t size_to_read = MIN(remain_bytes, (size_t)BLOCK_SIZE);

		if (size_to_read + offset > BLOCK_SIZE)
			size_to_read = BLOCK_SIZE - offset;

		res = tee_fs_htree_read_block(&fdp->ht, start_block_num, block);
		if (res != TEE_SUCCESS)
			goto exit;

		memcpy(data_ptr, block + offset, size_to_read);

		data_ptr += size_to_read;
		remain_bytes -= size_to_read;
		pos += size_to_read;

		start_block_num++;
	}
	res = TEE_SUCCESS;
exit:
	if (block)
		put_tmp_block(block);
	return res;
}

static TEE_Result ree_fs_read(struct tee_file_handle *fh, size_t pos,
			      void *buf, size_t *len)
{
	TEE_Result res;

	mutex_lock(&ree_fs_mutex);
	res = ree_fs_read_primitive(fh, pos, buf, len);
	mutex_unlock(&ree_fs_mutex);

	return res;
}

static TEE_Result ree_fs_write_primitive(struct tee_file_handle *fh, size_t pos,
					 const void *buf, size_t len)
{
	TEE_Result res;
	struct tee_fs_fd *fdp = (struct tee_fs_fd *)fh;
	size_t file_size;

	if (!len)
		return TEE_SUCCESS;

	file_size = tee_fs_htree_get_meta(fdp->ht)->length;

	if ((pos + len) < len)
		return TEE_ERROR_BAD_PARAMETERS;

	if (file_size < pos) {
		res = ree_fs_ftruncate_internal(fdp, pos);
		if (res != TEE_SUCCESS)
			return res;
	}

	return out_of_place_write(fdp, pos, buf, len);
}

static TEE_Result ree_fs_open_primitive(bool create, uint8_t *hash,
					const TEE_UUID *uuid,
					struct tee_fs_dirfile_fileh *dfh,
					struct tee_file_handle **fh)
{
	TEE_Result res;
	struct tee_fs_fd *fdp;

	fdp = calloc(1, sizeof(struct tee_fs_fd));
	if (!fdp)
		return TEE_ERROR_OUT_OF_MEMORY;
	fdp->fd = -1;
	fdp->uuid = uuid;

	if (create)
		res = tee_fs_rpc_create_dfh(OPTEE_RPC_CMD_FS,
					    dfh, &fdp->fd);
	else
		res = tee_fs_rpc_open_dfh(OPTEE_RPC_CMD_FS, dfh, &fdp->fd);

	if (res != TEE_SUCCESS)
		goto out;

	res = tee_fs_htree_open(create, hash, uuid, &ree_fs_storage_ops,
				fdp, &fdp->ht);
out:
	if (res == TEE_SUCCESS) {
		if (dfh)
			fdp->dfh = *dfh;
		else
			fdp->dfh.idx = -1;
		*fh = (struct tee_file_handle *)fdp;
	} else {
		if (fdp->fd != -1)
			tee_fs_rpc_close(OPTEE_RPC_CMD_FS, fdp->fd);
		if (create)
			tee_fs_rpc_remove_dfh(OPTEE_RPC_CMD_FS, dfh);
		free(fdp);
	}

	return res;
}

static void ree_fs_close_primitive(struct tee_file_handle *fh)
{
	struct tee_fs_fd *fdp = (struct tee_fs_fd *)fh;

	if (fdp) {
		tee_fs_htree_close(&fdp->ht);
		tee_fs_rpc_close(OPTEE_RPC_CMD_FS, fdp->fd);
		free(fdp);
	}
}

static TEE_Result ree_dirf_commit_writes(struct tee_file_handle *fh,
					 uint8_t *hash)
{
	TEE_Result res;
	struct tee_fs_fd *fdp = (struct tee_fs_fd *)fh;

	res = tee_fs_htree_sync_to_storage(&fdp->ht, fdp->dfh.hash);

	if (!res && hash)
		memcpy(hash, fdp->dfh.hash, sizeof(fdp->dfh.hash));

	return res;
}

static const struct tee_fs_dirfile_operations ree_dirf_ops = {
	.open = ree_fs_open_primitive,
	.close = ree_fs_close_primitive,
	.read = ree_fs_read_primitive,
	.write = ree_fs_write_primitive,
	.commit_writes = ree_dirf_commit_writes,
};

static struct tee_fs_dirfile_dirh *ree_fs_dirh;
static size_t ree_fs_dirh_refcount;

#ifdef CFG_RPMB_FS
static struct tee_file_handle *ree_fs_rpmb_fh;

static TEE_Result open_dirh(struct tee_fs_dirfile_dirh **dirh)
{
	TEE_Result res;
	uint8_t hash[TEE_FS_HTREE_HASH_SIZE];
	uint8_t *hashp = NULL;
	const char fname[] = "dirfile.db.hash";

	res = tee_rpmb_fs_raw_open(fname, false, &ree_fs_rpmb_fh);
	if (!res) {
		size_t l = sizeof(hash);

		res = rpmb_fs_ops.read(ree_fs_rpmb_fh, 0, hash, &l);
		if (res)
			return res;
		if (l == sizeof(hash))
			hashp = hash;
	} else if (res == TEE_ERROR_ITEM_NOT_FOUND) {
		res = tee_rpmb_fs_raw_open(fname, true, &ree_fs_rpmb_fh);
	}
	if (res)
		return res;

	res = tee_fs_dirfile_open(false, hashp, &ree_dirf_ops, dirh);
	if (res == TEE_ERROR_ITEM_NOT_FOUND)
		res = tee_fs_dirfile_open(true, NULL, &ree_dirf_ops, dirh);

	if (res)
		rpmb_fs_ops.close(&ree_fs_rpmb_fh);

	return res;
}

static TEE_Result commit_dirh_writes(struct tee_fs_dirfile_dirh *dirh)
{
	TEE_Result res;
	uint8_t hash[TEE_FS_HTREE_HASH_SIZE];

	res = tee_fs_dirfile_commit_writes(dirh, hash);
	if (res)
		return res;
	return rpmb_fs_ops.write(ree_fs_rpmb_fh, 0, hash, sizeof(hash));
}

static void close_dirh(struct tee_fs_dirfile_dirh **dirh)
{
	tee_fs_dirfile_close(*dirh);
	*dirh = NULL;
	rpmb_fs_ops.close(&ree_fs_rpmb_fh);
}

#else /*!CFG_RPMB_FS*/
static TEE_Result open_dirh(struct tee_fs_dirfile_dirh **dirh)
{
	TEE_Result res;

	res = tee_fs_dirfile_open(false, NULL, &ree_dirf_ops, dirh);
	if (res == TEE_ERROR_ITEM_NOT_FOUND)
		return tee_fs_dirfile_open(true, NULL, &ree_dirf_ops, dirh);

	return res;
}

static TEE_Result commit_dirh_writes(struct tee_fs_dirfile_dirh *dirh)
{
	return tee_fs_dirfile_commit_writes(dirh, NULL);
}

static void close_dirh(struct tee_fs_dirfile_dirh **dirh)
{
	tee_fs_dirfile_close(*dirh);
	*dirh = NULL;
}
#endif /*!CFG_RPMB_FS*/

static TEE_Result get_dirh(struct tee_fs_dirfile_dirh **dirh)
{
	if (!ree_fs_dirh) {
		TEE_Result res = open_dirh(&ree_fs_dirh);

		if (res) {
			*dirh = NULL;
			return res;
		}
	}
	ree_fs_dirh_refcount++;
	assert(ree_fs_dirh);
	assert(ree_fs_dirh_refcount);
	*dirh = ree_fs_dirh;
	return TEE_SUCCESS;
}

static void put_dirh_primitive(bool close)
{
	assert(ree_fs_dirh_refcount);

	/*
	 * During the execution of one of the ree_fs_ops ree_fs_dirh is
	 * guareteed to be a valid pointer. But when the fop has returned
	 * another thread may get an error or something causing that fop
	 * to do a put with close=1.
	 *
	 * For all fops but ree_fs_close() there's a call to get_dirh() to
	 * get a new dirh which will open it again if it was closed before.
	 * But in the ree_fs_close() case there's no call to get_dirh()
	 * only to this function, put_dirh_primitive(), and in this case
	 * ree_fs_dirh may actually be NULL.
	 */
	ree_fs_dirh_refcount--;
	if (ree_fs_dirh && (!ree_fs_dirh_refcount || close))
		close_dirh(&ree_fs_dirh);
}

static void put_dirh(struct tee_fs_dirfile_dirh *dirh, bool close)
{
	if (dirh) {
		assert(dirh == ree_fs_dirh);
		put_dirh_primitive(close);
	}
}

static TEE_Result ree_fs_open(struct tee_pobj *po, size_t *size,
			      struct tee_file_handle **fh)
{
	TEE_Result res;
	struct tee_fs_dirfile_dirh *dirh = NULL;
	struct tee_fs_dirfile_fileh dfh;

	mutex_lock(&ree_fs_mutex);

	res = get_dirh(&dirh);
	if (res != TEE_SUCCESS)
		goto out;

	res = tee_fs_dirfile_find(dirh, &po->uuid, po->obj_id, po->obj_id_len,
				  &dfh);
	if (res != TEE_SUCCESS)
		goto out;

	res = ree_fs_open_primitive(false, dfh.hash, &po->uuid, &dfh, fh);
	if (res == TEE_ERROR_ITEM_NOT_FOUND) {
		/*
		 * If the object isn't found someone has tampered with it,
		 * treat it as corrupt.
		 */
		res = TEE_ERROR_CORRUPT_OBJECT;
	} else if (!res && size) {
		struct tee_fs_fd *fdp = (struct tee_fs_fd *)*fh;

		*size = tee_fs_htree_get_meta(fdp->ht)->length;
	}

out:
	if (res)
		put_dirh(dirh, false);
	mutex_unlock(&ree_fs_mutex);

	return res;
}

static TEE_Result set_name(struct tee_fs_dirfile_dirh *dirh,
			   struct tee_fs_fd *fdp, struct tee_pobj *po,
			   bool overwrite)
{
	TEE_Result res;
	bool have_old_dfh = false;
	struct tee_fs_dirfile_fileh old_dfh = { .idx = -1 };

	res = tee_fs_dirfile_find(dirh, &po->uuid, po->obj_id, po->obj_id_len,
				  &old_dfh);
	if (!overwrite && !res)
		return TEE_ERROR_ACCESS_CONFLICT;

	if (!res)
		have_old_dfh = true;

	/*
	 * If old_dfh wasn't found, the idx will be -1 and
	 * tee_fs_dirfile_rename() will allocate a new index.
	 */
	fdp->dfh.idx = old_dfh.idx;
	old_dfh.idx = -1;
	res = tee_fs_dirfile_rename(dirh, &po->uuid, &fdp->dfh,
				    po->obj_id, po->obj_id_len);
	if (res)
		return res;

	res = commit_dirh_writes(dirh);
	if (res)
		return res;

	if (have_old_dfh)
		tee_fs_rpc_remove_dfh(OPTEE_RPC_CMD_FS, &old_dfh);

	return TEE_SUCCESS;
}

static void ree_fs_close(struct tee_file_handle **fh)
{
	if (*fh) {
		mutex_lock(&ree_fs_mutex);
		put_dirh_primitive(false);
		ree_fs_close_primitive(*fh);
		*fh = NULL;
		mutex_unlock(&ree_fs_mutex);

	}
}

static TEE_Result ree_fs_create(struct tee_pobj *po, bool overwrite,
				const void *head, size_t head_size,
				const void *attr, size_t attr_size,
				const void *data, size_t data_size,
				struct tee_file_handle **fh)
{
	struct tee_fs_fd *fdp;
	struct tee_fs_dirfile_dirh *dirh = NULL;
	struct tee_fs_dirfile_fileh dfh;
	TEE_Result res;
	size_t pos = 0;

	*fh = NULL;
	mutex_lock(&ree_fs_mutex);

	res = get_dirh(&dirh);
	if (res)
		goto out;

	res = tee_fs_dirfile_get_tmp(dirh, &dfh);
	if (res)
		goto out;

	res = ree_fs_open_primitive(true, dfh.hash, &po->uuid, &dfh, fh);
	if (res)
		goto out;

	if (head && head_size) {
		res = ree_fs_write_primitive(*fh, pos, head, head_size);
		if (res)
			goto out;
		pos += head_size;
	}

	if (attr && attr_size) {
		res = ree_fs_write_primitive(*fh, pos, attr, attr_size);
		if (res)
			goto out;
		pos += attr_size;
	}

	if (data && data_size) {
		res = ree_fs_write_primitive(*fh, pos, data, data_size);
		if (res)
			goto out;
	}

	fdp = (struct tee_fs_fd *)*fh;
	res = tee_fs_htree_sync_to_storage(&fdp->ht, fdp->dfh.hash);
	if (res)
		goto out;

	res = set_name(dirh, fdp, po, overwrite);
out:
	if (res) {
		put_dirh(dirh, true);
		if (*fh) {
			ree_fs_close_primitive(*fh);
			*fh = NULL;
			tee_fs_rpc_remove_dfh(OPTEE_RPC_CMD_FS, &dfh);
		}
	}
	mutex_unlock(&ree_fs_mutex);

	return res;
}

static TEE_Result ree_fs_write(struct tee_file_handle *fh, size_t pos,
			       const void *buf, size_t len)
{
	TEE_Result res;
	struct tee_fs_dirfile_dirh *dirh = NULL;
	struct tee_fs_fd *fdp = (struct tee_fs_fd *)fh;

	mutex_lock(&ree_fs_mutex);

	res = get_dirh(&dirh);
	if (res)
		goto out;

	res = ree_fs_write_primitive(fh, pos, buf, len);
	if (res)
		goto out;

	res = tee_fs_htree_sync_to_storage(&fdp->ht, fdp->dfh.hash);
	if (res)
		goto out;

	res = tee_fs_dirfile_update_hash(dirh, &fdp->dfh);
	if (res)
		goto out;
	res = commit_dirh_writes(dirh);
out:
	put_dirh(dirh, res);
	mutex_unlock(&ree_fs_mutex);

	return res;
}

static TEE_Result ree_fs_rename(struct tee_pobj *old, struct tee_pobj *new,
				bool overwrite)
{
	TEE_Result res;
	struct tee_fs_dirfile_dirh *dirh = NULL;
	struct tee_fs_dirfile_fileh dfh;
	struct tee_fs_dirfile_fileh remove_dfh = { .idx = -1 };

	if (!new)
		return TEE_ERROR_BAD_PARAMETERS;

	mutex_lock(&ree_fs_mutex);
	res = get_dirh(&dirh);
	if (res)
		goto out;

	res = tee_fs_dirfile_find(dirh, &new->uuid, new->obj_id,
				  new->obj_id_len, &remove_dfh);
	if (!res && !overwrite) {
		res = TEE_ERROR_ACCESS_CONFLICT;
		goto out;
	}

	res = tee_fs_dirfile_find(dirh, &old->uuid, old->obj_id,
				  old->obj_id_len, &dfh);
	if (res)
		goto out;

	res = tee_fs_dirfile_rename(dirh, &new->uuid, &dfh, new->obj_id,
				    new->obj_id_len);
	if (res)
		goto out;

	if (remove_dfh.idx != -1) {
		res = tee_fs_dirfile_remove(dirh, &remove_dfh);
		if (res)
			goto out;
	}

	res = commit_dirh_writes(dirh);
	if (res)
		goto out;

	if (remove_dfh.idx != -1)
		tee_fs_rpc_remove_dfh(OPTEE_RPC_CMD_FS, &remove_dfh);

out:
	put_dirh(dirh, res);
	mutex_unlock(&ree_fs_mutex);

	return res;

}

static TEE_Result ree_fs_remove(struct tee_pobj *po)
{
	TEE_Result res;
	struct tee_fs_dirfile_dirh *dirh = NULL;
	struct tee_fs_dirfile_fileh dfh;

	mutex_lock(&ree_fs_mutex);
	res = get_dirh(&dirh);
	if (res)
		goto out;

	res = tee_fs_dirfile_find(dirh, &po->uuid, po->obj_id, po->obj_id_len,
				  &dfh);
	if (res)
		goto out;

	res = tee_fs_dirfile_remove(dirh, &dfh);
	if (res)
		goto out;

	res = commit_dirh_writes(dirh);
	if (res)
		goto out;

	tee_fs_rpc_remove_dfh(OPTEE_RPC_CMD_FS, &dfh);

	assert(tee_fs_dirfile_find(dirh, &po->uuid, po->obj_id, po->obj_id_len,
				   &dfh));
out:
	put_dirh(dirh, res);
	mutex_unlock(&ree_fs_mutex);

	return res;
}

static TEE_Result ree_fs_truncate(struct tee_file_handle *fh, size_t len)
{
	TEE_Result res;
	struct tee_fs_dirfile_dirh *dirh = NULL;
	struct tee_fs_fd *fdp = (struct tee_fs_fd *)fh;

	mutex_lock(&ree_fs_mutex);

	res = get_dirh(&dirh);
	if (res)
		goto out;

	res = ree_fs_ftruncate_internal(fdp, len);
	if (res)
		goto out;

	res = tee_fs_htree_sync_to_storage(&fdp->ht, fdp->dfh.hash);
	if (res)
		goto out;

	res = tee_fs_dirfile_update_hash(dirh, &fdp->dfh);
	if (res)
		goto out;
	res = commit_dirh_writes(dirh);
out:
	put_dirh(dirh, res);
	mutex_unlock(&ree_fs_mutex);

	return res;
}

static TEE_Result ree_fs_opendir_rpc(const TEE_UUID *uuid,
				     struct tee_fs_dir **dir)

{
	TEE_Result res;
	struct tee_fs_dir *d = calloc(1, sizeof(*d));

	if (!d)
		return TEE_ERROR_OUT_OF_MEMORY;

	d->uuid = uuid;

	mutex_lock(&ree_fs_mutex);

	res = get_dirh(&d->dirh);
	if (res)
		goto out;

	/* See that there's at least one file */
	d->idx = -1;
	d->d.oidlen = sizeof(d->d.oid);
	res = tee_fs_dirfile_get_next(d->dirh, d->uuid, &d->idx, d->d.oid,
				      &d->d.oidlen);
	d->idx = -1;

out:
	if (!res) {
		*dir = d;
	} else {
		if (d)
			put_dirh(d->dirh, false);
		free(d);
	}
	mutex_unlock(&ree_fs_mutex);

	return res;
}

static void ree_fs_closedir_rpc(struct tee_fs_dir *d)
{
	if (d) {
		mutex_lock(&ree_fs_mutex);

		put_dirh(d->dirh, false);
		free(d);

		mutex_unlock(&ree_fs_mutex);
	}
}

static TEE_Result ree_fs_readdir_rpc(struct tee_fs_dir *d,
				     struct tee_fs_dirent **ent)
{
	TEE_Result res;

	mutex_lock(&ree_fs_mutex);

	d->d.oidlen = sizeof(d->d.oid);
	res = tee_fs_dirfile_get_next(d->dirh, d->uuid, &d->idx, d->d.oid,
				      &d->d.oidlen);
	if (res == TEE_SUCCESS)
		*ent = &d->d;

	mutex_unlock(&ree_fs_mutex);

	return res;
}

const struct tee_file_operations ree_fs_ops = {
	.open = ree_fs_open,
	.create = ree_fs_create,
	.close = ree_fs_close,
	.read = ree_fs_read,
	.write = ree_fs_write,
	.truncate = ree_fs_truncate,
	.rename = ree_fs_rename,
	.remove = ree_fs_remove,
	.opendir = ree_fs_opendir_rpc,
	.closedir = ree_fs_closedir_rpc,
	.readdir = ree_fs_readdir_rpc,
};
