/**
 * node.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"

void f2fs_alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid)
{
	struct f2fs_nm_info *nm_i = NM_I(sbi);
	nid_t i;

	for (i = 0; i < nm_i->max_nid; i++)
		if(f2fs_test_bit(i, nm_i->nid_bitmap) == 0)
			break;

	ASSERT(i < nm_i->max_nid);
	f2fs_set_bit(i, nm_i->nid_bitmap);
	*nid = i;
}

void f2fs_release_nid(struct f2fs_sb_info *sbi, nid_t nid)
{
	struct f2fs_nm_info *nm_i = NM_I(sbi);

	ASSERT(nid < nm_i->max_nid);
	ASSERT(f2fs_test_bit(nid, nm_i->nid_bitmap));

	f2fs_clear_bit(nid, nm_i->nid_bitmap);
}

int f2fs_rebuild_qf_inode(struct f2fs_sb_info *sbi, int qtype)
{
	struct f2fs_node *raw_node = NULL;
	struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
	struct f2fs_summary sum;
	struct node_info ni;
	nid_t ino = QUOTA_INO(sb, qtype);
	block_t blkaddr = NULL_ADDR;
	__u64 cp_ver = cur_cp_version(ckpt);
	int ret = 0;

	raw_node = calloc(F2FS_BLKSIZE, 1);
	if (raw_node == NULL) {
		MSG(1, "\tError: Calloc Failed for raw_node!!!\n");
		return -ENOMEM;
	}
	f2fs_init_qf_inode(sb, raw_node, qtype, time(NULL));

	if (is_set_ckpt_flags(ckpt, CP_CRC_RECOVERY_FLAG))
		cp_ver |= (cur_cp_crc(ckpt) << 32);
	raw_node->footer.cp_ver = cpu_to_le64(cp_ver);

	get_node_info(sbi, ino, &ni);
	set_summary(&sum, ino, 0, ni.version);
	ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_HOT_NODE, 1);
	if (ret) {
		MSG(1, "\tError: Failed to reserve new block!\n");
		goto err_out;
	}

	ret = write_inode(raw_node, blkaddr);
	if (ret < 0) {
		MSG(1, "\tError: While rebuilding the quota inode to disk!\n");
		goto err_out;
	}
	update_nat_blkaddr(sbi, ino, ino, blkaddr);

	f2fs_clear_bit(ino, F2FS_FSCK(sbi)->nat_area_bitmap);
	f2fs_set_bit(ino, NM_I(sbi)->nid_bitmap);
	DBG(1, "Rebuild quota inode ([%3d] ino [0x%x]) at offset:0x%x\n",
						qtype, ino, blkaddr);
err_out:
	free(raw_node);
	return ret;
}

void set_data_blkaddr(struct dnode_of_data *dn)
{
	__le32 *addr_array;
	struct f2fs_node *node_blk = dn->node_blk;
	unsigned int ofs_in_node = dn->ofs_in_node;

	addr_array = blkaddr_in_node(node_blk);
	addr_array[ofs_in_node] = cpu_to_le32(dn->data_blkaddr);
	if (dn->node_blk != dn->inode_blk)
		dn->ndirty = 1;
	else
		dn->idirty = 1;
}

/*
 * In this function, we get a new node blk, and write back
 * node_blk would be sloadd in RAM, linked by dn->node_blk
 */
block_t new_node_block(struct f2fs_sb_info *sbi,
				struct dnode_of_data *dn, unsigned int ofs)
{
	struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
	struct f2fs_node *f2fs_inode;
	struct f2fs_node *node_blk;
	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
	struct f2fs_summary sum;
	struct node_info ni;
	block_t blkaddr = NULL_ADDR;
	int type;
	int ret;

	f2fs_inode = dn->inode_blk;

	node_blk = calloc(BLOCK_SZ, 1);
	ASSERT(node_blk);

	node_blk->footer.nid = cpu_to_le32(dn->nid);
	node_blk->footer.ino = f2fs_inode->footer.ino;
	node_blk->footer.flag = cpu_to_le32(ofs << OFFSET_BIT_SHIFT);
	node_blk->footer.cp_ver = ckpt->checkpoint_ver;
	set_cold_node(node_blk, S_ISDIR(le16_to_cpu(f2fs_inode->i.i_mode)));

	type = CURSEG_COLD_NODE;
	if (IS_DNODE(node_blk)) {
		if (S_ISDIR(le16_to_cpu(f2fs_inode->i.i_mode)))
			type = CURSEG_HOT_NODE;
		else
			type = CURSEG_WARM_NODE;
	}

	if ((get_sb(feature) & cpu_to_le32(F2FS_FEATURE_RO)) &&
					type != CURSEG_HOT_NODE)
		type = CURSEG_HOT_NODE;

	get_node_info(sbi, dn->nid, &ni);
	set_summary(&sum, dn->nid, 0, ni.version);
	ret = reserve_new_block(sbi, &blkaddr, &sum, type, !ofs);
	if (ret) {
		free(node_blk);
		return 0;
	}

	/* update nat info */
	update_nat_blkaddr(sbi, le32_to_cpu(f2fs_inode->footer.ino),
						dn->nid, blkaddr);

	dn->node_blk = node_blk;
	inc_inode_blocks(dn);
	return blkaddr;
}

/*
 * get_node_path - Get the index path of pgoff_t block
 * @offset: offset in the current index node block.
 * @noffset: NO. of the index block within a file.
 * return: depth of the index path.
 *
 * By default, it sets inline_xattr and inline_data
 */
static int get_node_path(struct f2fs_node *node, long block,
				int offset[4], unsigned int noffset[4])
{
	const long direct_index = ADDRS_PER_INODE(&node->i);
	const long direct_blks = ADDRS_PER_BLOCK(&node->i);
	const long dptrs_per_blk = NIDS_PER_BLOCK;
	const long indirect_blks = ADDRS_PER_BLOCK(&node->i) * NIDS_PER_BLOCK;
	const long dindirect_blks = indirect_blks * NIDS_PER_BLOCK;
	int n = 0;
	int level = 0;

	noffset[0] = 0;
	if (block < direct_index) {
		offset[n] = block;
		goto got;
	}

	block -= direct_index;
	if (block < direct_blks) {
		offset[n++] = NODE_DIR1_BLOCK;
		noffset[n]= 1;
		offset[n] = block;
		level = 1;
		goto got;
	}
	block -= direct_blks;
	if (block < direct_blks) {
		offset[n++] = NODE_DIR2_BLOCK;
		noffset[n] = 2;
		offset[n] = block;
		level = 1;
		goto got;
	}
	block -= direct_blks;
	if (block < indirect_blks) {
		offset[n++] = NODE_IND1_BLOCK;
		noffset[n] = 3;
		offset[n++] = block / direct_blks;
		noffset[n] = 4 + offset[n - 1];
		offset[n] = block % direct_blks;
		level = 2;
		goto got;
	}
	block -= indirect_blks;
	if (block < indirect_blks) {
		offset[n++] = NODE_IND2_BLOCK;
		noffset[n] = 4 + dptrs_per_blk;
		offset[n++] = block / direct_blks;
		noffset[n] = 5 + dptrs_per_blk + offset[n - 1];
		offset[n] = block % direct_blks;
		level = 2;
		goto got;
	}
	block -= indirect_blks;
	if (block < dindirect_blks) {
		offset[n++] = NODE_DIND_BLOCK;
		noffset[n] = 5 + (dptrs_per_blk * 2);
		offset[n++] = block / indirect_blks;
		noffset[n] = 6 + (dptrs_per_blk * 2) +
			offset[n - 1] * (dptrs_per_blk + 1);
		offset[n++] = (block / direct_blks) % dptrs_per_blk;
		noffset[n] = 7 + (dptrs_per_blk * 2) +
			offset[n - 2] * (dptrs_per_blk + 1) +
			offset[n - 1];
		offset[n] = block % direct_blks;
		level = 3;
		goto got;
	} else {
		ASSERT(0);
	}
got:
	return level;
}

int get_dnode_of_data(struct f2fs_sb_info *sbi, struct dnode_of_data *dn,
						pgoff_t index, int mode)
{
	int offset[4];
	unsigned int noffset[4];
	struct f2fs_node *parent = NULL;
	nid_t nids[4];
	block_t nblk[4];
	struct node_info ni;
	int level, i;
	int ret;

	level = get_node_path(dn->inode_blk, index, offset, noffset);

	nids[0] = dn->nid;
	parent = dn->inode_blk;
	if (level != 0)
		nids[1] = get_nid(parent, offset[0], 1);
	else
		dn->node_blk = dn->inode_blk;

	get_node_info(sbi, nids[0], &ni);
	nblk[0] = ni.blk_addr;

	for (i = 1; i <= level; i++) {
		if (!nids[i] && mode == ALLOC_NODE) {
			f2fs_alloc_nid(sbi, &nids[i]);

			dn->nid = nids[i];

			/* Function new_node_blk get a new f2fs_node blk and update*/
			/* We should make sure that dn->node_blk == NULL*/
			nblk[i] = new_node_block(sbi, dn, noffset[i]);
			if (!nblk[i]) {
				f2fs_release_nid(sbi, nids[i]);
				c.alloc_failed = 1;
				return -EINVAL;
			}

			set_nid(parent, offset[i - 1], nids[i], i == 1);
		} else {
			/* If Sparse file no read API, */
			struct node_info ni;

			get_node_info(sbi, nids[i], &ni);
			dn->node_blk = calloc(BLOCK_SZ, 1);
			ASSERT(dn->node_blk);

			ret = dev_read_block(dn->node_blk, ni.blk_addr);
			ASSERT(ret >= 0);

			nblk[i] = ni.blk_addr;
		}

		if (mode == ALLOC_NODE){
			/* Parent node may have changed */
			ret = dev_write_block(parent, nblk[i - 1]);
			ASSERT(ret >= 0);
		}
		if (i != 1)
			free(parent);

		if (i < level) {
			parent = dn->node_blk;
			nids[i + 1] = get_nid(parent, offset[i], 0);
		}
	}

	dn->nid = nids[level];
	dn->ofs_in_node = offset[level];
	dn->data_blkaddr = datablock_addr(dn->node_blk, dn->ofs_in_node);
	dn->node_blkaddr = nblk[level];
	return 0;
}
