// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2018 Google LLC
 */
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/types.h>
#include <linux/mutex.h>
#include <linux/mm.h>
#include <linux/falloc.h>
#include <linux/slab.h>
#include <linux/crc32.h>
#include <linux/kernel.h>

#include "format.h"
#include "data_mgmt.h"

struct backing_file_context *incfs_alloc_bfc(struct mount_info *mi,
					     struct file *backing_file)
{
	struct backing_file_context *result = NULL;

	result = kzalloc(sizeof(*result), GFP_NOFS);
	if (!result)
		return ERR_PTR(-ENOMEM);

	result->bc_file = get_file(backing_file);
	result->bc_cred = mi->mi_owner;
	mutex_init(&result->bc_mutex);
	return result;
}

void incfs_free_bfc(struct backing_file_context *bfc)
{
	if (!bfc)
		return;

	if (bfc->bc_file)
		fput(bfc->bc_file);

	mutex_destroy(&bfc->bc_mutex);
	kfree(bfc);
}

static loff_t incfs_get_end_offset(struct file *f)
{
	/*
	 * This function assumes that file size and the end-offset
	 * are the same. This is not always true.
	 */
	return i_size_read(file_inode(f));
}

/*
 * Truncate the tail of the file to the given length.
 * Used to rollback partially successful multistep writes.
 */
static int truncate_backing_file(struct backing_file_context *bfc,
				loff_t new_end)
{
	struct inode *inode = NULL;
	struct dentry *dentry = NULL;
	loff_t old_end = 0;
	struct iattr attr;
	int result = 0;

	if (!bfc)
		return -EFAULT;

	LOCK_REQUIRED(bfc->bc_mutex);

	if (!bfc->bc_file)
		return -EFAULT;

	old_end = incfs_get_end_offset(bfc->bc_file);
	if (old_end == new_end)
		return 0;
	if (old_end < new_end)
		return -EINVAL;

	inode = bfc->bc_file->f_inode;
	dentry = bfc->bc_file->f_path.dentry;

	attr.ia_size = new_end;
	attr.ia_valid = ATTR_SIZE;

	inode_lock(inode);
	result = notify_change(&nop_mnt_idmap, dentry, &attr, NULL);
	inode_unlock(inode);

	return result;
}

static int write_to_bf(struct backing_file_context *bfc, const void *buf,
			size_t count, loff_t pos)
{
	ssize_t res = incfs_kwrite(bfc, buf, count, pos);

	if (res < 0)
		return res;
	if (res != count)
		return -EIO;
	return 0;
}

static int append_zeros_no_fallocate(struct backing_file_context *bfc,
				     size_t file_size, size_t len)
{
	u8 buffer[256] = {};
	size_t i;

	for (i = 0; i < len; i += sizeof(buffer)) {
		int to_write = len - i > sizeof(buffer)
			? sizeof(buffer) : len - i;
		int err = write_to_bf(bfc, buffer, to_write, file_size + i);

		if (err)
			return err;
	}

	return 0;
}

/* Append a given number of zero bytes to the end of the backing file. */
static int append_zeros(struct backing_file_context *bfc, size_t len)
{
	loff_t file_size = 0;
	loff_t new_last_byte_offset = 0;
	int result;

	if (!bfc)
		return -EFAULT;

	if (len == 0)
		return 0;

	LOCK_REQUIRED(bfc->bc_mutex);

	/*
	 * Allocate only one byte at the new desired end of the file.
	 * It will increase file size and create a zeroed area of
	 * a given size.
	 */
	file_size = incfs_get_end_offset(bfc->bc_file);
	new_last_byte_offset = file_size + len - 1;
	result = vfs_fallocate(bfc->bc_file, 0, new_last_byte_offset, 1);
	if (result != -EOPNOTSUPP)
		return result;

	return append_zeros_no_fallocate(bfc, file_size, len);
}

/*
 * Append a given metadata record to the backing file and update a previous
 * record to add the new record the the metadata list.
 */
static int append_md_to_backing_file(struct backing_file_context *bfc,
			      struct incfs_md_header *record)
{
	int result = 0;
	loff_t record_offset;
	loff_t file_pos;
	__le64 new_md_offset;
	size_t record_size;

	if (!bfc || !record)
		return -EFAULT;

	if (bfc->bc_last_md_record_offset < 0)
		return -EINVAL;

	LOCK_REQUIRED(bfc->bc_mutex);

	record_size = le16_to_cpu(record->h_record_size);
	file_pos = incfs_get_end_offset(bfc->bc_file);
	record->h_next_md_offset = 0;

	/* Write the metadata record to the end of the backing file */
	record_offset = file_pos;
	new_md_offset = cpu_to_le64(record_offset);
	result = write_to_bf(bfc, record, record_size, file_pos);
	if (result)
		return result;

	/* Update next metadata offset in a previous record or a superblock. */
	if (bfc->bc_last_md_record_offset) {
		/*
		 * Find a place in the previous md record where new record's
		 * offset needs to be saved.
		 */
		file_pos = bfc->bc_last_md_record_offset +
			offsetof(struct incfs_md_header, h_next_md_offset);
	} else {
		/*
		 * No metadata yet, file a place to update in the
		 * file_header.
		 */
		file_pos = offsetof(struct incfs_file_header,
				    fh_first_md_offset);
	}
	result = write_to_bf(bfc, &new_md_offset, sizeof(new_md_offset),
			     file_pos);
	if (result)
		return result;

	bfc->bc_last_md_record_offset = record_offset;
	return result;
}

/*
 * Reserve 0-filled space for the blockmap body, and append
 * incfs_blockmap metadata record pointing to it.
 */
int incfs_write_blockmap_to_backing_file(struct backing_file_context *bfc,
					 u32 block_count)
{
	struct incfs_blockmap blockmap = {};
	int result = 0;
	loff_t file_end = 0;
	size_t map_size = block_count * sizeof(struct incfs_blockmap_entry);

	if (!bfc)
		return -EFAULT;

	blockmap.m_header.h_md_entry_type = INCFS_MD_BLOCK_MAP;
	blockmap.m_header.h_record_size = cpu_to_le16(sizeof(blockmap));
	blockmap.m_header.h_next_md_offset = cpu_to_le64(0);
	blockmap.m_block_count = cpu_to_le32(block_count);

	LOCK_REQUIRED(bfc->bc_mutex);

	/* Reserve 0-filled space for the blockmap body in the backing file. */
	file_end = incfs_get_end_offset(bfc->bc_file);
	result = append_zeros(bfc, map_size);
	if (result)
		return result;

	/* Write blockmap metadata record pointing to the body written above. */
	blockmap.m_base_offset = cpu_to_le64(file_end);
	result = append_md_to_backing_file(bfc, &blockmap.m_header);
	if (result)
		/* Error, rollback file changes */
		truncate_backing_file(bfc, file_end);

	return result;
}

int incfs_write_signature_to_backing_file(struct backing_file_context *bfc,
					struct mem_range sig, u32 tree_size,
					loff_t *tree_offset, loff_t *sig_offset)
{
	struct incfs_file_signature sg = {};
	int result = 0;
	loff_t rollback_pos = 0;
	loff_t tree_area_pos = 0;
	size_t alignment = 0;

	if (!bfc)
		return -EFAULT;

	LOCK_REQUIRED(bfc->bc_mutex);

	rollback_pos = incfs_get_end_offset(bfc->bc_file);

	sg.sg_header.h_md_entry_type = INCFS_MD_SIGNATURE;
	sg.sg_header.h_record_size = cpu_to_le16(sizeof(sg));
	sg.sg_header.h_next_md_offset = cpu_to_le64(0);
	if (sig.data != NULL && sig.len > 0) {
		sg.sg_sig_size = cpu_to_le32(sig.len);
		sg.sg_sig_offset = cpu_to_le64(rollback_pos);

		result = write_to_bf(bfc, sig.data, sig.len, rollback_pos);
		if (result)
			goto err;
	}

	tree_area_pos = incfs_get_end_offset(bfc->bc_file);
	if (tree_size > 0) {
		if (tree_size > 5 * INCFS_DATA_FILE_BLOCK_SIZE) {
			/*
			 * If hash tree is big enough, it makes sense to
			 * align in the backing file for faster access.
			 */
			loff_t offset = round_up(tree_area_pos, PAGE_SIZE);

			alignment = offset - tree_area_pos;
			tree_area_pos = offset;
		}

		/*
		 * If root hash is not the only hash in the tree.
		 * reserve 0-filled space for the tree.
		 */
		result = append_zeros(bfc, tree_size + alignment);
		if (result)
			goto err;

		sg.sg_hash_tree_size = cpu_to_le32(tree_size);
		sg.sg_hash_tree_offset = cpu_to_le64(tree_area_pos);
	}

	/* Write a hash tree metadata record pointing to the hash tree above. */
	result = append_md_to_backing_file(bfc, &sg.sg_header);
err:
	if (result)
		/* Error, rollback file changes */
		truncate_backing_file(bfc, rollback_pos);
	else {
		if (tree_offset)
			*tree_offset = tree_area_pos;
		if (sig_offset)
			*sig_offset = rollback_pos;
	}

	return result;
}

static int write_new_status_to_backing_file(struct backing_file_context *bfc,
				       u32 data_blocks_written,
				       u32 hash_blocks_written)
{
	int result;
	loff_t rollback_pos;
	struct incfs_status is = {
		.is_header = {
			.h_md_entry_type = INCFS_MD_STATUS,
			.h_record_size = cpu_to_le16(sizeof(is)),
		},
		.is_data_blocks_written = cpu_to_le32(data_blocks_written),
		.is_hash_blocks_written = cpu_to_le32(hash_blocks_written),
	};

	LOCK_REQUIRED(bfc->bc_mutex);
	rollback_pos = incfs_get_end_offset(bfc->bc_file);
	result = append_md_to_backing_file(bfc, &is.is_header);
	if (result)
		truncate_backing_file(bfc, rollback_pos);

	return result;
}

int incfs_write_status_to_backing_file(struct backing_file_context *bfc,
				       loff_t status_offset,
				       u32 data_blocks_written,
				       u32 hash_blocks_written)
{
	struct incfs_status is;
	int result;

	if (!bfc)
		return -EFAULT;

	if (status_offset == 0)
		return write_new_status_to_backing_file(bfc,
				data_blocks_written, hash_blocks_written);

	result = incfs_kread(bfc, &is, sizeof(is), status_offset);
	if (result != sizeof(is))
		return -EIO;

	is.is_data_blocks_written = cpu_to_le32(data_blocks_written);
	is.is_hash_blocks_written = cpu_to_le32(hash_blocks_written);
	result = incfs_kwrite(bfc, &is, sizeof(is), status_offset);
	if (result != sizeof(is))
		return -EIO;

	return 0;
}

int incfs_write_verity_signature_to_backing_file(
		struct backing_file_context *bfc, struct mem_range signature,
		loff_t *offset)
{
	struct incfs_file_verity_signature vs = {};
	int result;
	loff_t pos;

	/* No verity signature section is equivalent to an empty section */
	if (signature.data == NULL || signature.len == 0)
		return 0;

	pos = incfs_get_end_offset(bfc->bc_file);

	vs = (struct incfs_file_verity_signature) {
		.vs_header = (struct incfs_md_header) {
			.h_md_entry_type = INCFS_MD_VERITY_SIGNATURE,
			.h_record_size = cpu_to_le16(sizeof(vs)),
			.h_next_md_offset = cpu_to_le64(0),
		},
		.vs_size = cpu_to_le32(signature.len),
		.vs_offset = cpu_to_le64(pos),
	};

	result = write_to_bf(bfc, signature.data, signature.len, pos);
	if (result)
		goto err;

	result = append_md_to_backing_file(bfc, &vs.vs_header);
	if (result)
		goto err;

	*offset = pos;
err:
	if (result)
		/* Error, rollback file changes */
		truncate_backing_file(bfc, pos);
	return result;
}

/*
 * Write a backing file header
 * It should always be called only on empty file.
 * fh.fh_first_md_offset is 0 for now, but will be updated
 * once first metadata record is added.
 */
int incfs_write_fh_to_backing_file(struct backing_file_context *bfc,
				   incfs_uuid_t *uuid, u64 file_size)
{
	struct incfs_file_header fh = {};
	loff_t file_pos = 0;

	if (!bfc)
		return -EFAULT;

	fh.fh_magic = cpu_to_le64(INCFS_MAGIC_NUMBER);
	fh.fh_version = cpu_to_le64(INCFS_FORMAT_CURRENT_VER);
	fh.fh_header_size = cpu_to_le16(sizeof(fh));
	fh.fh_first_md_offset = cpu_to_le64(0);
	fh.fh_data_block_size = cpu_to_le16(INCFS_DATA_FILE_BLOCK_SIZE);

	fh.fh_file_size = cpu_to_le64(file_size);
	fh.fh_uuid = *uuid;

	LOCK_REQUIRED(bfc->bc_mutex);

	file_pos = incfs_get_end_offset(bfc->bc_file);
	if (file_pos != 0)
		return -EEXIST;

	return write_to_bf(bfc, &fh, sizeof(fh), file_pos);
}

/*
 * Write a backing file header for a mapping file
 * It should always be called only on empty file.
 */
int incfs_write_mapping_fh_to_backing_file(struct backing_file_context *bfc,
				incfs_uuid_t *uuid, u64 file_size, u64 offset)
{
	struct incfs_file_header fh = {};
	loff_t file_pos = 0;

	if (!bfc)
		return -EFAULT;

	fh.fh_magic = cpu_to_le64(INCFS_MAGIC_NUMBER);
	fh.fh_version = cpu_to_le64(INCFS_FORMAT_CURRENT_VER);
	fh.fh_header_size = cpu_to_le16(sizeof(fh));
	fh.fh_original_offset = cpu_to_le64(offset);
	fh.fh_data_block_size = cpu_to_le16(INCFS_DATA_FILE_BLOCK_SIZE);

	fh.fh_mapped_file_size = cpu_to_le64(file_size);
	fh.fh_original_uuid = *uuid;
	fh.fh_flags = cpu_to_le32(INCFS_FILE_MAPPED);

	LOCK_REQUIRED(bfc->bc_mutex);

	file_pos = incfs_get_end_offset(bfc->bc_file);
	if (file_pos != 0)
		return -EEXIST;

	return write_to_bf(bfc, &fh, sizeof(fh), file_pos);
}

/* Write a given data block and update file's blockmap to point it. */
int incfs_write_data_block_to_backing_file(struct backing_file_context *bfc,
				     struct mem_range block, int block_index,
				     loff_t bm_base_off, u16 flags)
{
	struct incfs_blockmap_entry bm_entry = {};
	int result = 0;
	loff_t data_offset = 0;
	loff_t bm_entry_off =
		bm_base_off + sizeof(struct incfs_blockmap_entry) * block_index;

	if (!bfc)
		return -EFAULT;

	if (block.len >= (1 << 16) || block_index < 0)
		return -EINVAL;

	LOCK_REQUIRED(bfc->bc_mutex);

	data_offset = incfs_get_end_offset(bfc->bc_file);
	if (data_offset <= bm_entry_off) {
		/* Blockmap entry is beyond the file's end. It is not normal. */
		return -EINVAL;
	}

	/* Write the block data at the end of the backing file. */
	result = write_to_bf(bfc, block.data, block.len, data_offset);
	if (result)
		return result;

	/* Update the blockmap to point to the newly written data. */
	bm_entry.me_data_offset_lo = cpu_to_le32((u32)data_offset);
	bm_entry.me_data_offset_hi = cpu_to_le16((u16)(data_offset >> 32));
	bm_entry.me_data_size = cpu_to_le16((u16)block.len);
	bm_entry.me_flags = cpu_to_le16(flags);

	return write_to_bf(bfc, &bm_entry, sizeof(bm_entry),
				bm_entry_off);
}

int incfs_write_hash_block_to_backing_file(struct backing_file_context *bfc,
					   struct mem_range block,
					   int block_index,
					   loff_t hash_area_off,
					   loff_t bm_base_off,
					   loff_t file_size)
{
	struct incfs_blockmap_entry bm_entry = {};
	int result;
	loff_t data_offset = 0;
	loff_t file_end = 0;
	loff_t bm_entry_off =
		bm_base_off +
		sizeof(struct incfs_blockmap_entry) *
			(block_index + get_blocks_count_for_size(file_size));

	if (!bfc)
		return -EFAULT;

	LOCK_REQUIRED(bfc->bc_mutex);

	data_offset = hash_area_off + block_index * INCFS_DATA_FILE_BLOCK_SIZE;
	file_end = incfs_get_end_offset(bfc->bc_file);
	if (data_offset + block.len > file_end) {
		/* Block is located beyond the file's end. It is not normal. */
		return -EINVAL;
	}

	result = write_to_bf(bfc, block.data, block.len, data_offset);
	if (result)
		return result;

	bm_entry.me_data_offset_lo = cpu_to_le32((u32)data_offset);
	bm_entry.me_data_offset_hi = cpu_to_le16((u16)(data_offset >> 32));
	bm_entry.me_data_size = cpu_to_le16(INCFS_DATA_FILE_BLOCK_SIZE);

	return write_to_bf(bfc, &bm_entry, sizeof(bm_entry), bm_entry_off);
}

int incfs_read_blockmap_entry(struct backing_file_context *bfc, int block_index,
			loff_t bm_base_off,
			struct incfs_blockmap_entry *bm_entry)
{
	int error = incfs_read_blockmap_entries(bfc, bm_entry, block_index, 1,
						bm_base_off);

	if (error < 0)
		return error;

	if (error == 0)
		return -EIO;

	if (error != 1)
		return -EFAULT;

	return 0;
}

int incfs_read_blockmap_entries(struct backing_file_context *bfc,
		struct incfs_blockmap_entry *entries,
		int start_index, int blocks_number,
		loff_t bm_base_off)
{
	loff_t bm_entry_off =
		bm_base_off + sizeof(struct incfs_blockmap_entry) * start_index;
	const size_t bytes_to_read = sizeof(struct incfs_blockmap_entry)
					* blocks_number;
	int result = 0;

	if (!bfc || !entries)
		return -EFAULT;

	if (start_index < 0 || bm_base_off <= 0)
		return -ENODATA;

	result = incfs_kread(bfc, entries, bytes_to_read, bm_entry_off);
	if (result < 0)
		return result;
	return result / sizeof(*entries);
}

int incfs_read_file_header(struct backing_file_context *bfc,
			   loff_t *first_md_off, incfs_uuid_t *uuid,
			   u64 *file_size, u32 *flags)
{
	ssize_t bytes_read = 0;
	struct incfs_file_header fh = {};

	if (!bfc || !first_md_off)
		return -EFAULT;

	bytes_read = incfs_kread(bfc, &fh, sizeof(fh), 0);
	if (bytes_read < 0)
		return bytes_read;

	if (bytes_read < sizeof(fh))
		return -EBADMSG;

	if (le64_to_cpu(fh.fh_magic) != INCFS_MAGIC_NUMBER)
		return -EILSEQ;

	if (le64_to_cpu(fh.fh_version) > INCFS_FORMAT_CURRENT_VER)
		return -EILSEQ;

	if (le16_to_cpu(fh.fh_data_block_size) != INCFS_DATA_FILE_BLOCK_SIZE)
		return -EILSEQ;

	if (le16_to_cpu(fh.fh_header_size) != sizeof(fh))
		return -EILSEQ;

	if (first_md_off)
		*first_md_off = le64_to_cpu(fh.fh_first_md_offset);
	if (uuid)
		*uuid = fh.fh_uuid;
	if (file_size)
		*file_size = le64_to_cpu(fh.fh_file_size);
	if (flags)
		*flags = le32_to_cpu(fh.fh_flags);
	return 0;
}

/*
 * Read through metadata records from the backing file one by one
 * and call provided metadata handlers.
 */
int incfs_read_next_metadata_record(struct backing_file_context *bfc,
			      struct metadata_handler *handler)
{
	const ssize_t max_md_size = INCFS_MAX_METADATA_RECORD_SIZE;
	ssize_t bytes_read = 0;
	size_t md_record_size = 0;
	loff_t next_record = 0;
	int res = 0;
	struct incfs_md_header *md_hdr = NULL;

	if (!bfc || !handler)
		return -EFAULT;

	if (handler->md_record_offset == 0)
		return -EPERM;

	memset(&handler->md_buffer, 0, max_md_size);
	bytes_read = incfs_kread(bfc, &handler->md_buffer, max_md_size,
				 handler->md_record_offset);
	if (bytes_read < 0)
		return bytes_read;
	if (bytes_read < sizeof(*md_hdr))
		return -EBADMSG;

	md_hdr = &handler->md_buffer.md_header;
	next_record = le64_to_cpu(md_hdr->h_next_md_offset);
	md_record_size = le16_to_cpu(md_hdr->h_record_size);

	if (md_record_size > max_md_size) {
		pr_warn("incfs: The record is too large. Size: %zu",
				md_record_size);
		return -EBADMSG;
	}

	if (bytes_read < md_record_size) {
		pr_warn("incfs: The record hasn't been fully read.");
		return -EBADMSG;
	}

	if (next_record <= handler->md_record_offset && next_record != 0) {
		pr_warn("incfs: Next record (%lld) points back in file.",
			next_record);
		return -EBADMSG;
	}

	switch (md_hdr->h_md_entry_type) {
	case INCFS_MD_NONE:
		break;
	case INCFS_MD_BLOCK_MAP:
		if (handler->handle_blockmap)
			res = handler->handle_blockmap(
				&handler->md_buffer.blockmap, handler);
		break;
	case INCFS_MD_FILE_ATTR:
		/*
		 * File attrs no longer supported, ignore section for
		 * compatibility
		 */
		break;
	case INCFS_MD_SIGNATURE:
		if (handler->handle_signature)
			res = handler->handle_signature(
				&handler->md_buffer.signature, handler);
		break;
	case INCFS_MD_STATUS:
		if (handler->handle_status)
			res = handler->handle_status(
				&handler->md_buffer.status, handler);
		break;
	case INCFS_MD_VERITY_SIGNATURE:
		if (handler->handle_verity_signature)
			res = handler->handle_verity_signature(
				&handler->md_buffer.verity_signature, handler);
		break;
	default:
		res = -ENOTSUPP;
		break;
	}

	if (!res) {
		if (next_record == 0) {
			/*
			 * Zero offset for the next record means that the last
			 * metadata record has just been processed.
			 */
			bfc->bc_last_md_record_offset =
				handler->md_record_offset;
		}
		handler->md_prev_record_offset = handler->md_record_offset;
		handler->md_record_offset = next_record;
	}
	return res;
}

ssize_t incfs_kread(struct backing_file_context *bfc, void *buf, size_t size,
		    loff_t pos)
{
	const struct cred *old_cred = override_creds(bfc->bc_cred);
	int ret = kernel_read(bfc->bc_file, buf, size, &pos);

	revert_creds(old_cred);
	return ret;
}

ssize_t incfs_kwrite(struct backing_file_context *bfc, const void *buf,
		     size_t size, loff_t pos)
{
	const struct cred *old_cred = override_creds(bfc->bc_cred);
	int ret = kernel_write(bfc->bc_file, buf, size, &pos);

	revert_creds(old_cred);
	return ret;
}
