/*
 * (C) Copyright 2011 - 2012 Samsung Electronics
 * EXT4 filesystem implementation in Uboot by
 * Uma Shankar <uma.shankar@samsung.com>
 * Manjunatha C Achar <a.manjunatha@samsung.com>
 *
 * Journal data structures and headers for Journaling feature of ext4
 * have been referred from JBD2 (Journaling Block device 2)
 * implementation in Linux Kernel.
 * Written by Stephen C. Tweedie <sct@redhat.com>
 *
 * Copyright 1998-2000 Red Hat, Inc --- All Rights Reserved
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <ext4fs.h>
#include <malloc.h>
#include <ext_common.h>
#include "ext4_common.h"

static struct revoke_blk_list *revk_blk_list;
static struct revoke_blk_list *prev_node;
static int first_node = true;

int gindex;
int gd_index;
int jrnl_blk_idx;
struct journal_log *journal_ptr[MAX_JOURNAL_ENTRIES];
struct dirty_blocks *dirty_block_ptr[MAX_JOURNAL_ENTRIES];

int ext4fs_init_journal(void)
{
	int i;
	char *temp = NULL;
	struct ext_filesystem *fs = get_fs();

	/* init globals */
	revk_blk_list = NULL;
	prev_node = NULL;
	gindex = 0;
	gd_index = 0;
	jrnl_blk_idx = 1;

	for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
		journal_ptr[i] = zalloc(sizeof(struct journal_log));
		if (!journal_ptr[i])
			goto fail;
		dirty_block_ptr[i] = zalloc(sizeof(struct dirty_blocks));
		if (!dirty_block_ptr[i])
			goto fail;
		journal_ptr[i]->buf = NULL;
		journal_ptr[i]->blknr = -1;

		dirty_block_ptr[i]->buf = NULL;
		dirty_block_ptr[i]->blknr = -1;
	}

	if (fs->blksz == 4096) {
		temp = zalloc(fs->blksz);
		if (!temp)
			goto fail;
		journal_ptr[gindex]->buf = zalloc(fs->blksz);
		if (!journal_ptr[gindex]->buf)
			goto fail;
		ext4fs_devread(0, 0, fs->blksz, temp);
		memcpy(temp + SUPERBLOCK_SIZE, fs->sb, SUPERBLOCK_SIZE);
		memcpy(journal_ptr[gindex]->buf, temp, fs->blksz);
		journal_ptr[gindex++]->blknr = 0;
		free(temp);
	} else {
		journal_ptr[gindex]->buf = zalloc(fs->blksz);
		if (!journal_ptr[gindex]->buf)
			goto fail;
		memcpy(journal_ptr[gindex]->buf, fs->sb, SUPERBLOCK_SIZE);
		journal_ptr[gindex++]->blknr = 1;
	}

	/* Check the file system state using journal super block */
	if (ext4fs_check_journal_state(SCAN))
		goto fail;
	/* Check the file system state using journal super block */
	if (ext4fs_check_journal_state(RECOVER))
		goto fail;

	return 0;
fail:
	return -1;
}

void ext4fs_dump_metadata(void)
{
	struct ext_filesystem *fs = get_fs();
	int i;
	for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
		if (dirty_block_ptr[i]->blknr == -1)
			break;
		put_ext4((uint64_t) ((uint64_t)dirty_block_ptr[i]->blknr *
				(uint64_t)fs->blksz), dirty_block_ptr[i]->buf,
								fs->blksz);
	}
}

void ext4fs_free_journal(void)
{
	int i;
	for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
		if (dirty_block_ptr[i]->blknr == -1)
			break;
		if (dirty_block_ptr[i]->buf)
			free(dirty_block_ptr[i]->buf);
	}

	for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
		if (journal_ptr[i]->blknr == -1)
			break;
		if (journal_ptr[i]->buf)
			free(journal_ptr[i]->buf);
	}

	for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
		if (journal_ptr[i])
			free(journal_ptr[i]);
		if (dirty_block_ptr[i])
			free(dirty_block_ptr[i]);
	}
	gindex = 0;
	gd_index = 0;
	jrnl_blk_idx = 1;
}

int ext4fs_log_gdt(char *gd_table)
{
	struct ext_filesystem *fs = get_fs();
	short i;
	long int var = fs->gdtable_blkno;
	for (i = 0; i < fs->no_blk_pergdt; i++) {
		journal_ptr[gindex]->buf = zalloc(fs->blksz);
		if (!journal_ptr[gindex]->buf)
			return -ENOMEM;
		memcpy(journal_ptr[gindex]->buf, gd_table, fs->blksz);
		gd_table += fs->blksz;
		journal_ptr[gindex++]->blknr = var++;
	}

	return 0;
}

/*
 * This function stores the backup copy of meta data in RAM
 * journal_buffer -- Buffer containing meta data
 * blknr -- Block number on disk of the meta data buffer
 */
int ext4fs_log_journal(char *journal_buffer, long int blknr)
{
	struct ext_filesystem *fs = get_fs();
	short i;

	if (!journal_buffer) {
		printf("Invalid input arguments %s\n", __func__);
		return -EINVAL;
	}

	for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
		if (journal_ptr[i]->blknr == -1)
			break;
		if (journal_ptr[i]->blknr == blknr)
			return 0;
	}

	journal_ptr[gindex]->buf = zalloc(fs->blksz);
	if (!journal_ptr[gindex]->buf)
		return -ENOMEM;

	memcpy(journal_ptr[gindex]->buf, journal_buffer, fs->blksz);
	journal_ptr[gindex++]->blknr = blknr;

	return 0;
}

/*
 * This function stores the modified meta data in RAM
 * metadata_buffer -- Buffer containing meta data
 * blknr -- Block number on disk of the meta data buffer
 */
int ext4fs_put_metadata(char *metadata_buffer, long int blknr)
{
	struct ext_filesystem *fs = get_fs();
	if (!metadata_buffer) {
		printf("Invalid input arguments %s\n", __func__);
		return -EINVAL;
	}
	dirty_block_ptr[gd_index]->buf = zalloc(fs->blksz);
	if (!dirty_block_ptr[gd_index]->buf)
		return -ENOMEM;
	memcpy(dirty_block_ptr[gd_index]->buf, metadata_buffer, fs->blksz);
	dirty_block_ptr[gd_index++]->blknr = blknr;

	return 0;
}

void print_revoke_blks(char *revk_blk)
{
	int offset;
	int max;
	long int blocknr;
	struct journal_revoke_header_t *header;

	if (revk_blk == NULL)
		return;

	header = (struct journal_revoke_header_t *) revk_blk;
	offset = sizeof(struct journal_revoke_header_t);
	max = be32_to_cpu(header->r_count);
	printf("total bytes %d\n", max);

	while (offset < max) {
		blocknr = be32_to_cpu(*((long int *)(revk_blk + offset)));
		printf("revoke blknr is %ld\n", blocknr);
		offset += 4;
	}
}

static struct revoke_blk_list *_get_node(void)
{
	struct revoke_blk_list *tmp_node;
	tmp_node = zalloc(sizeof(struct revoke_blk_list));
	if (tmp_node == NULL)
		return NULL;
	tmp_node->content = NULL;
	tmp_node->next = NULL;

	return tmp_node;
}

void ext4fs_push_revoke_blk(char *buffer)
{
	struct revoke_blk_list *node = NULL;
	struct ext_filesystem *fs = get_fs();
	if (buffer == NULL) {
		printf("buffer ptr is NULL\n");
		return;
	}
	node = _get_node();
	if (!node) {
		printf("_get_node: malloc failed\n");
		return;
	}

	node->content = zalloc(fs->blksz);
	if (node->content == NULL)
		return;
	memcpy(node->content, buffer, fs->blksz);

	if (first_node == true) {
		revk_blk_list = node;
		prev_node = node;
		 first_node = false;
	} else {
		prev_node->next = node;
		prev_node = node;
	}
}

void ext4fs_free_revoke_blks(void)
{
	struct revoke_blk_list *tmp_node = revk_blk_list;
	struct revoke_blk_list *next_node = NULL;

	while (tmp_node != NULL) {
		if (tmp_node->content)
			free(tmp_node->content);
		tmp_node = tmp_node->next;
	}

	tmp_node = revk_blk_list;
	while (tmp_node != NULL) {
		next_node = tmp_node->next;
		free(tmp_node);
		tmp_node = next_node;
	}

	revk_blk_list = NULL;
	prev_node = NULL;
	first_node = true;
}

int check_blknr_for_revoke(long int blknr, int sequence_no)
{
	struct journal_revoke_header_t *header;
	int offset;
	int max;
	long int blocknr;
	char *revk_blk;
	struct revoke_blk_list *tmp_revk_node = revk_blk_list;
	while (tmp_revk_node != NULL) {
		revk_blk = tmp_revk_node->content;

		header = (struct journal_revoke_header_t *) revk_blk;
		if (sequence_no < be32_to_cpu(header->r_header.h_sequence)) {
			offset = sizeof(struct journal_revoke_header_t);
			max = be32_to_cpu(header->r_count);

			while (offset < max) {
				blocknr = be32_to_cpu(*((long int *)
						  (revk_blk + offset)));
				if (blocknr == blknr)
					goto found;
				offset += 4;
			}
		}
		tmp_revk_node = tmp_revk_node->next;
	}

	return -1;

found:
	return 0;
}

/*
 * This function parses the journal blocks and replays the
 * suceessful transactions. A transaction is successfull
 * if commit block is found for a descriptor block
 * The tags in descriptor block contain the disk block
 * numbers of the metadata  to be replayed
 */
void recover_transaction(int prev_desc_logical_no)
{
	struct ext2_inode inode_journal;
	struct ext_filesystem *fs = get_fs();
	struct journal_header_t *jdb;
	long int blknr;
	char *p_jdb;
	int ofs, flags;
	int i;
	struct ext3_journal_block_tag *tag;
	char *temp_buff = zalloc(fs->blksz);
	char *metadata_buff = zalloc(fs->blksz);
	if (!temp_buff || !metadata_buff)
		goto fail;
	i = prev_desc_logical_no;
	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO,
			  (struct ext2_inode *)&inode_journal);
	blknr = read_allocated_block((struct ext2_inode *)
				     &inode_journal, i);
	ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
		       temp_buff);
	p_jdb = (char *)temp_buff;
	jdb = (struct journal_header_t *) temp_buff;
	ofs = sizeof(struct journal_header_t);

	do {
		tag = (struct ext3_journal_block_tag *)&p_jdb[ofs];
		ofs += sizeof(struct ext3_journal_block_tag);

		if (ofs > fs->blksz)
			break;

		flags = be32_to_cpu(tag->flags);
		if (!(flags & EXT3_JOURNAL_FLAG_SAME_UUID))
			ofs += 16;

		i++;
		debug("\t\ttag %u\n", be32_to_cpu(tag->block));
		if (revk_blk_list != NULL) {
			if (check_blknr_for_revoke(be32_to_cpu(tag->block),
				be32_to_cpu(jdb->h_sequence)) == 0)
				continue;
		}
		blknr = read_allocated_block(&inode_journal, i);
		ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0,
			       fs->blksz, metadata_buff);
		put_ext4((uint64_t)((uint64_t)be32_to_cpu(tag->block) * (uint64_t)fs->blksz),
			 metadata_buff, (uint32_t) fs->blksz);
	} while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG));
fail:
	free(temp_buff);
	free(metadata_buff);
}

void print_jrnl_status(int recovery_flag)
{
	if (recovery_flag == RECOVER)
		printf("Journal Recovery Completed\n");
	else
		printf("Journal Scan Completed\n");
}

int ext4fs_check_journal_state(int recovery_flag)
{
	int i;
	int DB_FOUND = NO;
	long int blknr;
	int transaction_state = TRANSACTION_COMPLETE;
	int prev_desc_logical_no = 0;
	int curr_desc_logical_no = 0;
	int ofs, flags;
	struct ext2_inode inode_journal;
	struct journal_superblock_t *jsb = NULL;
	struct journal_header_t *jdb = NULL;
	char *p_jdb = NULL;
	struct ext3_journal_block_tag *tag = NULL;
	char *temp_buff = NULL;
	char *temp_buff1 = NULL;
	struct ext_filesystem *fs = get_fs();

	temp_buff = zalloc(fs->blksz);
	if (!temp_buff)
		return -ENOMEM;
	temp_buff1 = zalloc(fs->blksz);
	if (!temp_buff1) {
		free(temp_buff);
		return -ENOMEM;
	}

	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
	blknr = read_allocated_block(&inode_journal, EXT2_JOURNAL_SUPERBLOCK);
	ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
		       temp_buff);
	jsb = (struct journal_superblock_t *) temp_buff;

	if (fs->sb->feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
		if (recovery_flag == RECOVER)
			printf("Recovery required\n");
	} else {
		if (recovery_flag == RECOVER)
			printf("File System is consistent\n");
		goto end;
	}

	if (be32_to_cpu(jsb->s_start) == 0)
		goto end;

	if (!(jsb->s_feature_compat &
				cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM)))
		jsb->s_feature_compat |=
				cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM);

	i = be32_to_cpu(jsb->s_first);
	while (1) {
		blknr = read_allocated_block(&inode_journal, i);
		memset(temp_buff1, '\0', fs->blksz);
		ext4fs_devread((lbaint_t)blknr * fs->sect_perblk,
			       0, fs->blksz, temp_buff1);
		jdb = (struct journal_header_t *) temp_buff1;

		if (be32_to_cpu(jdb->h_blocktype) ==
		    EXT3_JOURNAL_DESCRIPTOR_BLOCK) {
			if (be32_to_cpu(jdb->h_sequence) !=
			    be32_to_cpu(jsb->s_sequence)) {
				print_jrnl_status(recovery_flag);
				break;
			}

			curr_desc_logical_no = i;
			if (transaction_state == TRANSACTION_COMPLETE)
				transaction_state = TRANSACTION_RUNNING;
			else
				return -1;
			p_jdb = (char *)temp_buff1;
			ofs = sizeof(struct journal_header_t);
			do {
				tag = (struct ext3_journal_block_tag *)
				    &p_jdb[ofs];
				ofs += sizeof(struct ext3_journal_block_tag);
				if (ofs > fs->blksz)
					break;
				flags = be32_to_cpu(tag->flags);
				if (!(flags & EXT3_JOURNAL_FLAG_SAME_UUID))
					ofs += 16;
				i++;
				debug("\t\ttag %u\n", be32_to_cpu(tag->block));
			} while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG));
			i++;
			DB_FOUND = YES;
		} else if (be32_to_cpu(jdb->h_blocktype) ==
				EXT3_JOURNAL_COMMIT_BLOCK) {
			if (be32_to_cpu(jdb->h_sequence) !=
			     be32_to_cpu(jsb->s_sequence)) {
				print_jrnl_status(recovery_flag);
				break;
			}

			if (transaction_state == TRANSACTION_RUNNING ||
					(DB_FOUND == NO)) {
				transaction_state = TRANSACTION_COMPLETE;
				i++;
				jsb->s_sequence =
					cpu_to_be32(be32_to_cpu(
						jsb->s_sequence) + 1);
			}
			prev_desc_logical_no = curr_desc_logical_no;
			if ((recovery_flag == RECOVER) && (DB_FOUND == YES))
				recover_transaction(prev_desc_logical_no);

			DB_FOUND = NO;
		} else if (be32_to_cpu(jdb->h_blocktype) ==
				EXT3_JOURNAL_REVOKE_BLOCK) {
			if (be32_to_cpu(jdb->h_sequence) !=
			    be32_to_cpu(jsb->s_sequence)) {
				print_jrnl_status(recovery_flag);
				break;
			}
			if (recovery_flag == SCAN)
				ext4fs_push_revoke_blk((char *)jdb);
			i++;
		} else {
			debug("Else Case\n");
			if (be32_to_cpu(jdb->h_sequence) !=
			    be32_to_cpu(jsb->s_sequence)) {
				print_jrnl_status(recovery_flag);
				break;
			}
		}
	}

end:
	if (recovery_flag == RECOVER) {
		jsb->s_start = cpu_to_be32(1);
		jsb->s_sequence = cpu_to_be32(be32_to_cpu(jsb->s_sequence) + 1);
		/* get the superblock */
		ext4_read_superblock((char *)fs->sb);
		fs->sb->feature_incompat |= EXT3_FEATURE_INCOMPAT_RECOVER;

		/* Update the super block */
		put_ext4((uint64_t) (SUPERBLOCK_SIZE),
			 (struct ext2_sblock *)fs->sb,
			 (uint32_t) SUPERBLOCK_SIZE);
		ext4_read_superblock((char *)fs->sb);

		blknr = read_allocated_block(&inode_journal,
					 EXT2_JOURNAL_SUPERBLOCK);
		put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz),
			 (struct journal_superblock_t *)temp_buff,
			 (uint32_t) fs->blksz);
		ext4fs_free_revoke_blks();
	}
	free(temp_buff);
	free(temp_buff1);

	return 0;
}

static void update_descriptor_block(long int blknr)
{
	int i;
	long int jsb_blknr;
	struct journal_header_t jdb;
	struct ext3_journal_block_tag tag;
	struct ext2_inode inode_journal;
	struct journal_superblock_t *jsb = NULL;
	char *buf = NULL;
	char *temp = NULL;
	struct ext_filesystem *fs = get_fs();
	char *temp_buff = zalloc(fs->blksz);
	if (!temp_buff)
		return;

	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
	jsb_blknr = read_allocated_block(&inode_journal,
					 EXT2_JOURNAL_SUPERBLOCK);
	ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz,
		       temp_buff);
	jsb = (struct journal_superblock_t *) temp_buff;

	jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_DESCRIPTOR_BLOCK);
	jdb.h_magic = cpu_to_be32(EXT3_JOURNAL_MAGIC_NUMBER);
	jdb.h_sequence = jsb->s_sequence;
	buf = zalloc(fs->blksz);
	if (!buf) {
		free(temp_buff);
		return;
	}
	temp = buf;
	memcpy(buf, &jdb, sizeof(struct journal_header_t));
	temp += sizeof(struct journal_header_t);

	for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
		if (journal_ptr[i]->blknr == -1)
			break;

		tag.block = cpu_to_be32(journal_ptr[i]->blknr);
		tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_SAME_UUID);
		memcpy(temp, &tag, sizeof(struct ext3_journal_block_tag));
		temp = temp + sizeof(struct ext3_journal_block_tag);
	}

	tag.block = cpu_to_be32(journal_ptr[--i]->blknr);
	tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_LAST_TAG);
	memcpy(temp - sizeof(struct ext3_journal_block_tag), &tag,
	       sizeof(struct ext3_journal_block_tag));
	put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), buf, (uint32_t) fs->blksz);

	free(temp_buff);
	free(buf);
}

static void update_commit_block(long int blknr)
{
	struct journal_header_t jdb;
	struct ext_filesystem *fs = get_fs();
	char *buf = NULL;
	struct ext2_inode inode_journal;
	struct journal_superblock_t *jsb;
	long int jsb_blknr;
	char *temp_buff = zalloc(fs->blksz);
	if (!temp_buff)
		return;

	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO,
			  &inode_journal);
	jsb_blknr = read_allocated_block(&inode_journal,
					 EXT2_JOURNAL_SUPERBLOCK);
	ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz,
		       temp_buff);
	jsb = (struct journal_superblock_t *) temp_buff;

	jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_COMMIT_BLOCK);
	jdb.h_magic = cpu_to_be32(EXT3_JOURNAL_MAGIC_NUMBER);
	jdb.h_sequence = jsb->s_sequence;
	buf = zalloc(fs->blksz);
	if (!buf) {
		free(temp_buff);
		return;
	}
	memcpy(buf, &jdb, sizeof(struct journal_header_t));
	put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), buf, (uint32_t) fs->blksz);

	free(temp_buff);
	free(buf);
}

void ext4fs_update_journal(void)
{
	struct ext2_inode inode_journal;
	struct ext_filesystem *fs = get_fs();
	long int blknr;
	int i;
	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
	blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++);
	update_descriptor_block(blknr);
	for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
		if (journal_ptr[i]->blknr == -1)
			break;
		blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++);
		put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz),
			 journal_ptr[i]->buf, fs->blksz);
	}
	blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++);
	update_commit_block(blknr);
	printf("update journal finished\n");
}
