/*
 * (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
 * This file is part of the Linux kernel and is made available under
 * the terms of the GNU General Public License, version 2, or at your
 * option, any later version, incorporated herein by reference.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#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 */
		ext4fs_devread(SUPERBLOCK_SECTOR, 0, SUPERBLOCK_SIZE,
			       (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);
		ext4fs_devread(SUPERBLOCK_SECTOR, 0, SUPERBLOCK_SIZE,
			       (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");
}
