// SPDX-License-Identifier: GPL-2.0+
/*
 * (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>
 *
 * ext4ls and ext4load : Based on ext2 ls load support in Uboot.
 *
 * (C) Copyright 2004
 * esd gmbh <www.esd-electronics.com>
 * Reinhard Arlt <reinhard.arlt@esd-electronics.com>
 *
 * based on code from grub2 fs/ext2.c and fs/fshelp.c by
 * GRUB  --  GRand Unified Bootloader
 * Copyright (C) 2003, 2004  Free Software Foundation, Inc.
 *
 * ext4write : Based on generic ext4 protocol.
 */

#include <blk.h>
#include <ext_common.h>
#include <ext4fs.h>
#include <log.h>
#include <malloc.h>
#include <memalign.h>
#include <part.h>
#include <stddef.h>
#include <linux/stat.h>
#include <linux/time.h>
#include <asm/byteorder.h>
#include "ext4_common.h"

struct ext2_data *ext4fs_root;
struct ext2fs_node *ext4fs_file;
__le32 *ext4fs_indir1_block;
int ext4fs_indir1_size;
int ext4fs_indir1_blkno = -1;
__le32 *ext4fs_indir2_block;
int ext4fs_indir2_size;
int ext4fs_indir2_blkno = -1;

__le32 *ext4fs_indir3_block;
int ext4fs_indir3_size;
int ext4fs_indir3_blkno = -1;
struct ext2_inode *g_parent_inode;
static int symlinknest;

#if defined(CONFIG_EXT4_WRITE)
struct ext2_block_group *ext4fs_get_group_descriptor
	(const struct ext_filesystem *fs, uint32_t bg_idx)
{
	return (struct ext2_block_group *)(fs->gdtable + (bg_idx * fs->gdsize));
}

static inline void ext4fs_sb_free_inodes_dec(struct ext2_sblock *sb)
{
	sb->free_inodes = cpu_to_le32(le32_to_cpu(sb->free_inodes) - 1);
}

static inline void ext4fs_sb_free_blocks_dec(struct ext2_sblock *sb)
{
	uint64_t free_blocks = le32_to_cpu(sb->free_blocks);
	free_blocks += (uint64_t)le32_to_cpu(sb->free_blocks_high) << 32;
	free_blocks--;

	sb->free_blocks = cpu_to_le32(free_blocks & 0xffffffff);
	sb->free_blocks_high = cpu_to_le16(free_blocks >> 32);
}

static inline void ext4fs_bg_free_inodes_dec
	(struct ext2_block_group *bg, const struct ext_filesystem *fs)
{
	uint32_t free_inodes = le16_to_cpu(bg->free_inodes);
	if (fs->gdsize == 64)
		free_inodes += le16_to_cpu(bg->free_inodes_high) << 16;
	free_inodes--;

	bg->free_inodes = cpu_to_le16(free_inodes & 0xffff);
	if (fs->gdsize == 64)
		bg->free_inodes_high = cpu_to_le16(free_inodes >> 16);
}

static inline void ext4fs_bg_free_blocks_dec
	(struct ext2_block_group *bg, const struct ext_filesystem *fs)
{
	uint32_t free_blocks = le16_to_cpu(bg->free_blocks);
	if (fs->gdsize == 64)
		free_blocks += le16_to_cpu(bg->free_blocks_high) << 16;
	free_blocks--;

	bg->free_blocks = cpu_to_le16(free_blocks & 0xffff);
	if (fs->gdsize == 64)
		bg->free_blocks_high = cpu_to_le16(free_blocks >> 16);
}

static inline void ext4fs_bg_itable_unused_dec
	(struct ext2_block_group *bg, const struct ext_filesystem *fs)
{
	uint32_t free_inodes = le16_to_cpu(bg->bg_itable_unused);
	if (fs->gdsize == 64)
		free_inodes += le16_to_cpu(bg->bg_itable_unused_high) << 16;
	free_inodes--;

	bg->bg_itable_unused = cpu_to_le16(free_inodes & 0xffff);
	if (fs->gdsize == 64)
		bg->bg_itable_unused_high = cpu_to_le16(free_inodes >> 16);
}

uint64_t ext4fs_sb_get_free_blocks(const struct ext2_sblock *sb)
{
	uint64_t free_blocks = le32_to_cpu(sb->free_blocks);
	free_blocks += (uint64_t)le32_to_cpu(sb->free_blocks_high) << 32;
	return free_blocks;
}

void ext4fs_sb_set_free_blocks(struct ext2_sblock *sb, uint64_t free_blocks)
{
	sb->free_blocks = cpu_to_le32(free_blocks & 0xffffffff);
	sb->free_blocks_high = cpu_to_le16(free_blocks >> 32);
}

uint32_t ext4fs_bg_get_free_blocks(const struct ext2_block_group *bg,
				   const struct ext_filesystem *fs)
{
	uint32_t free_blocks = le16_to_cpu(bg->free_blocks);
	if (fs->gdsize == 64)
		free_blocks += le16_to_cpu(bg->free_blocks_high) << 16;
	return free_blocks;
}

static inline
uint32_t ext4fs_bg_get_free_inodes(const struct ext2_block_group *bg,
				   const struct ext_filesystem *fs)
{
	uint32_t free_inodes = le16_to_cpu(bg->free_inodes);
	if (fs->gdsize == 64)
		free_inodes += le16_to_cpu(bg->free_inodes_high) << 16;
	return free_inodes;
}

static inline uint16_t ext4fs_bg_get_flags(const struct ext2_block_group *bg)
{
	return le16_to_cpu(bg->bg_flags);
}

static inline void ext4fs_bg_set_flags(struct ext2_block_group *bg,
				       uint16_t flags)
{
	bg->bg_flags = cpu_to_le16(flags);
}

/* Block number of the block bitmap */
uint64_t ext4fs_bg_get_block_id(const struct ext2_block_group *bg,
				const struct ext_filesystem *fs)
{
	uint64_t block_nr = le32_to_cpu(bg->block_id);
	if (fs->gdsize == 64)
		block_nr += (uint64_t)le32_to_cpu(bg->block_id_high) << 32;
	return block_nr;
}

/* Block number of the inode bitmap */
uint64_t ext4fs_bg_get_inode_id(const struct ext2_block_group *bg,
				const struct ext_filesystem *fs)
{
	uint64_t block_nr = le32_to_cpu(bg->inode_id);
	if (fs->gdsize == 64)
		block_nr += (uint64_t)le32_to_cpu(bg->inode_id_high) << 32;
	return block_nr;
}
#endif

/* Block number of the inode table */
uint64_t ext4fs_bg_get_inode_table_id(const struct ext2_block_group *bg,
				      const struct ext_filesystem *fs)
{
	uint64_t block_nr = le32_to_cpu(bg->inode_table_id);
	if (fs->gdsize == 64)
		block_nr +=
			(uint64_t)le32_to_cpu(bg->inode_table_id_high) << 32;
	return block_nr;
}

#if defined(CONFIG_EXT4_WRITE)
uint32_t ext4fs_div_roundup(uint32_t size, uint32_t n)
{
	uint32_t res = size / n;
	if (res * n != size)
		res++;

	return res;
}

void put_ext4(uint64_t off, const void *buf, uint32_t size)
{
	uint64_t startblock;
	uint64_t remainder;
	unsigned char *temp_ptr = NULL;
	struct ext_filesystem *fs = get_fs();
	int log2blksz = fs->dev_desc->log2blksz;
	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, sec_buf, fs->dev_desc->blksz);

	startblock = off >> log2blksz;
	startblock += part_offset;
	remainder = off & (uint64_t)(fs->dev_desc->blksz - 1);

	if (fs->dev_desc == NULL)
		return;

	if ((startblock + (size >> log2blksz)) >
	    (part_offset + fs->total_sect)) {
		printf("part_offset is " LBAFU "\n", part_offset);
		printf("total_sector is %llu\n", fs->total_sect);
		printf("error: overflow occurs\n");
		return;
	}

	if (remainder) {
		blk_dread(fs->dev_desc, startblock, 1, sec_buf);
		temp_ptr = sec_buf;
		memcpy((temp_ptr + remainder), (unsigned char *)buf, size);
		blk_dwrite(fs->dev_desc, startblock, 1, sec_buf);
	} else {
		if (size >> log2blksz != 0) {
			blk_dwrite(fs->dev_desc, startblock, size >> log2blksz,
				   (unsigned long *)buf);
		} else {
			blk_dread(fs->dev_desc, startblock, 1, sec_buf);
			temp_ptr = sec_buf;
			memcpy(temp_ptr, buf, size);
			blk_dwrite(fs->dev_desc, startblock, 1,
				   (unsigned long *)sec_buf);
		}
	}
}

static int _get_new_inode_no(unsigned char *buffer)
{
	struct ext_filesystem *fs = get_fs();
	unsigned char input;
	int operand, status;
	int count = 1;
	int j = 0;

	/* get the blocksize of the filesystem */
	unsigned char *ptr = buffer;
	while (*ptr == 255) {
		ptr++;
		count += 8;
		if (count > le32_to_cpu(ext4fs_root->sblock.inodes_per_group))
			return -1;
	}

	for (j = 0; j < fs->blksz; j++) {
		input = *ptr;
		int i = 0;
		while (i <= 7) {
			operand = 1 << i;
			status = input & operand;
			if (status) {
				i++;
				count++;
			} else {
				*ptr |= operand;
				return count;
			}
		}
		ptr = ptr + 1;
	}

	return -1;
}

static int _get_new_blk_no(unsigned char *buffer)
{
	int operand;
	int count = 0;
	int i;
	unsigned char *ptr = buffer;
	struct ext_filesystem *fs = get_fs();

	while (*ptr == 255) {
		ptr++;
		count += 8;
		if (count == (fs->blksz * 8))
			return -1;
	}

	if (fs->blksz == 1024)
		count += 1;

	for (i = 0; i <= 7; i++) {
		operand = 1 << i;
		if (*ptr & operand) {
			count++;
		} else {
			*ptr |= operand;
			return count;
		}
	}

	return -1;
}

int ext4fs_set_block_bmap(long int blockno, unsigned char *buffer, int index)
{
	int i, remainder, status;
	unsigned char *ptr = buffer;
	unsigned char operand;
	i = blockno / 8;
	remainder = blockno % 8;
	int blocksize = EXT2_BLOCK_SIZE(ext4fs_root);

	i = i - (index * blocksize);
	if (blocksize != 1024) {
		ptr = ptr + i;
		operand = 1 << remainder;
		status = *ptr & operand;
		if (status)
			return -1;

		*ptr = *ptr | operand;
		return 0;
	} else {
		if (remainder == 0) {
			ptr = ptr + i - 1;
			operand = (1 << 7);
		} else {
			ptr = ptr + i;
			operand = (1 << (remainder - 1));
		}
		status = *ptr & operand;
		if (status)
			return -1;

		*ptr = *ptr | operand;
		return 0;
	}
}

void ext4fs_reset_block_bmap(long int blockno, unsigned char *buffer, int index)
{
	int i, remainder, status;
	unsigned char *ptr = buffer;
	unsigned char operand;
	i = blockno / 8;
	remainder = blockno % 8;
	int blocksize = EXT2_BLOCK_SIZE(ext4fs_root);

	i = i - (index * blocksize);
	if (blocksize != 1024) {
		ptr = ptr + i;
		operand = (1 << remainder);
		status = *ptr & operand;
		if (status)
			*ptr = *ptr & ~(operand);
	} else {
		if (remainder == 0) {
			ptr = ptr + i - 1;
			operand = (1 << 7);
		} else {
			ptr = ptr + i;
			operand = (1 << (remainder - 1));
		}
		status = *ptr & operand;
		if (status)
			*ptr = *ptr & ~(operand);
	}
}

int ext4fs_set_inode_bmap(int inode_no, unsigned char *buffer, int index)
{
	int i, remainder, status;
	unsigned char *ptr = buffer;
	unsigned char operand;

	inode_no -= (index * le32_to_cpu(ext4fs_root->sblock.inodes_per_group));
	i = inode_no / 8;
	remainder = inode_no % 8;
	if (remainder == 0) {
		ptr = ptr + i - 1;
		operand = (1 << 7);
	} else {
		ptr = ptr + i;
		operand = (1 << (remainder - 1));
	}
	status = *ptr & operand;
	if (status)
		return -1;

	*ptr = *ptr | operand;

	return 0;
}

void ext4fs_reset_inode_bmap(int inode_no, unsigned char *buffer, int index)
{
	int i, remainder, status;
	unsigned char *ptr = buffer;
	unsigned char operand;

	inode_no -= (index * le32_to_cpu(ext4fs_root->sblock.inodes_per_group));
	i = inode_no / 8;
	remainder = inode_no % 8;
	if (remainder == 0) {
		ptr = ptr + i - 1;
		operand = (1 << 7);
	} else {
		ptr = ptr + i;
		operand = (1 << (remainder - 1));
	}
	status = *ptr & operand;
	if (status)
		*ptr = *ptr & ~(operand);
}

uint16_t ext4fs_checksum_update(uint32_t i)
{
	struct ext2_block_group *desc;
	struct ext_filesystem *fs = get_fs();
	uint16_t crc = 0;
	__le32 le32_i = cpu_to_le32(i);

	desc = ext4fs_get_group_descriptor(fs, i);
	if (le32_to_cpu(fs->sb->feature_ro_compat) & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) {
		int offset = offsetof(struct ext2_block_group, bg_checksum);

		crc = crc16(~0, (__u8 *)fs->sb->unique_id,
				   sizeof(fs->sb->unique_id));
		crc = crc16(crc, (__u8 *)&le32_i, sizeof(le32_i));
		crc = crc16(crc, (__u8 *)desc, offset);
		offset += sizeof(desc->bg_checksum);	/* skip checksum */
		assert(offset == sizeof(*desc));
		if (offset < fs->gdsize) {
			crc = crc16(crc, (__u8 *)desc + offset,
					   fs->gdsize - offset);
		}
	}

	return crc;
}

static int check_void_in_dentry(struct ext2_dirent *dir, char *filename)
{
	int dentry_length;
	int sizeof_void_space;
	int new_entry_byte_reqd;
	short padding_factor = 0;

	if (dir->namelen % 4 != 0)
		padding_factor = 4 - (dir->namelen % 4);

	dentry_length = sizeof(struct ext2_dirent) +
			dir->namelen + padding_factor;
	sizeof_void_space = le16_to_cpu(dir->direntlen) - dentry_length;
	if (sizeof_void_space == 0)
		return 0;

	padding_factor = 0;
	if (strlen(filename) % 4 != 0)
		padding_factor = 4 - (strlen(filename) % 4);

	new_entry_byte_reqd = strlen(filename) +
	    sizeof(struct ext2_dirent) + padding_factor;
	if (sizeof_void_space >= new_entry_byte_reqd) {
		dir->direntlen = cpu_to_le16(dentry_length);
		return sizeof_void_space;
	}

	return 0;
}

int ext4fs_update_parent_dentry(char *filename, int file_type)
{
	unsigned int *zero_buffer = NULL;
	char *root_first_block_buffer = NULL;
	int blk_idx;
	long int first_block_no_of_root = 0;
	int totalbytes = 0;
	unsigned int new_entry_byte_reqd;
	int sizeof_void_space = 0;
	int templength = 0;
	int inodeno = -1;
	int status;
	struct ext_filesystem *fs = get_fs();
	/* directory entry */
	struct ext2_dirent *dir;
	char *temp_dir = NULL;
	uint32_t new_blk_no;
	uint32_t new_size;
	uint32_t new_blockcnt;
	uint32_t directory_blocks;

	zero_buffer = zalloc(fs->blksz);
	if (!zero_buffer) {
		printf("No Memory\n");
		return -1;
	}
	root_first_block_buffer = zalloc(fs->blksz);
	if (!root_first_block_buffer) {
		free(zero_buffer);
		printf("No Memory\n");
		return -1;
	}
	new_entry_byte_reqd = ROUND(strlen(filename) +
				    sizeof(struct ext2_dirent), 4);
restart:
	directory_blocks = le32_to_cpu(g_parent_inode->size) >>
		LOG2_BLOCK_SIZE(ext4fs_root);
	blk_idx = directory_blocks - 1;

restart_read:
	/* read the block no allocated to a file */
	first_block_no_of_root = read_allocated_block(g_parent_inode, blk_idx,
						      NULL);
	if (first_block_no_of_root <= 0)
		goto fail;

	status = ext4fs_devread((lbaint_t)first_block_no_of_root
				* fs->sect_perblk,
				0, fs->blksz, root_first_block_buffer);
	if (status == 0)
		goto fail;

	if (ext4fs_log_journal(root_first_block_buffer, first_block_no_of_root))
		goto fail;
	dir = (struct ext2_dirent *)root_first_block_buffer;
	totalbytes = 0;

	while (le16_to_cpu(dir->direntlen) > 0) {
		unsigned short used_len = ROUND(dir->namelen +
		    sizeof(struct ext2_dirent), 4);

		/* last entry of block */
		if (fs->blksz - totalbytes == le16_to_cpu(dir->direntlen)) {

			/* check if new entry fits */
			if ((used_len + new_entry_byte_reqd) <=
			    le16_to_cpu(dir->direntlen)) {
				dir->direntlen = cpu_to_le16(used_len);
				break;
			} else {
				if (blk_idx > 0) {
					printf("Block full, trying previous\n");
					blk_idx--;
					goto restart_read;
				}
				printf("All blocks full: Allocate new\n");

				if (le32_to_cpu(g_parent_inode->flags) &
						EXT4_EXTENTS_FL) {
					printf("Directory uses extents\n");
					goto fail;
				}
				if (directory_blocks >= INDIRECT_BLOCKS) {
					printf("Directory exceeds limit\n");
					goto fail;
				}
				new_blk_no = ext4fs_get_new_blk_no();
				if (new_blk_no == -1) {
					printf("no block left to assign\n");
					goto fail;
				}
				put_ext4((uint64_t)new_blk_no * fs->blksz, zero_buffer, fs->blksz);
				g_parent_inode->b.blocks.
					dir_blocks[directory_blocks] =
					cpu_to_le32(new_blk_no);

				new_size = le32_to_cpu(g_parent_inode->size);
				new_size += fs->blksz;
				g_parent_inode->size = cpu_to_le32(new_size);

				new_blockcnt = le32_to_cpu(g_parent_inode->blockcnt);
				new_blockcnt += fs->blksz >> LOG2_SECTOR_SIZE;
				g_parent_inode->blockcnt = cpu_to_le32(new_blockcnt);

				if (ext4fs_put_metadata
				    (root_first_block_buffer,
				     first_block_no_of_root))
					goto fail;
				goto restart;
			}
		}

		templength = le16_to_cpu(dir->direntlen);
		totalbytes = totalbytes + templength;
		sizeof_void_space = check_void_in_dentry(dir, filename);
		if (sizeof_void_space)
			break;

		dir = (struct ext2_dirent *)((char *)dir + templength);
	}

	/* make a pointer ready for creating next directory entry */
	templength = le16_to_cpu(dir->direntlen);
	totalbytes = totalbytes + templength;
	dir = (struct ext2_dirent *)((char *)dir + templength);

	/* get the next available inode number */
	inodeno = ext4fs_get_new_inode_no();
	if (inodeno == -1) {
		printf("no inode left to assign\n");
		goto fail;
	}
	dir->inode = cpu_to_le32(inodeno);
	if (sizeof_void_space)
		dir->direntlen = cpu_to_le16(sizeof_void_space);
	else
		dir->direntlen = cpu_to_le16(fs->blksz - totalbytes);

	dir->namelen = strlen(filename);
	dir->filetype = file_type;
	temp_dir = (char *)dir;
	temp_dir = temp_dir + sizeof(struct ext2_dirent);
	memcpy(temp_dir, filename, strlen(filename));

	/* update or write  the 1st block of root inode */
	if (ext4fs_put_metadata(root_first_block_buffer,
				first_block_no_of_root))
		goto fail;

fail:
	free(zero_buffer);
	free(root_first_block_buffer);

	return inodeno;
}

static int search_dir(struct ext2_inode *parent_inode, char *dirname)
{
	int status;
	int inodeno = 0;
	int offset;
	int blk_idx;
	long int blknr;
	char *block_buffer = NULL;
	struct ext2_dirent *dir = NULL;
	struct ext_filesystem *fs = get_fs();
	uint32_t directory_blocks;
	char *direntname;

	directory_blocks = le32_to_cpu(parent_inode->size) >>
		LOG2_BLOCK_SIZE(ext4fs_root);

	block_buffer = zalloc(fs->blksz);
	if (!block_buffer)
		goto fail;

	/* get the block no allocated to a file */
	for (blk_idx = 0; blk_idx < directory_blocks; blk_idx++) {
		blknr = read_allocated_block(parent_inode, blk_idx, NULL);
		if (blknr <= 0)
			goto fail;

		/* read the directory block */
		status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk,
					0, fs->blksz, (char *)block_buffer);
		if (status == 0)
			goto fail;

		offset = 0;
		do {
			if (offset & 3) {
				printf("Badly aligned ext2_dirent\n");
				break;
			}

			dir = (struct ext2_dirent *)(block_buffer + offset);
			direntname = (char*)(dir) + sizeof(struct ext2_dirent);

			int direntlen = le16_to_cpu(dir->direntlen);
			if (direntlen < sizeof(struct ext2_dirent))
				break;

			if (dir->inode && (strlen(dirname) == dir->namelen) &&
			    (strncmp(dirname, direntname, dir->namelen) == 0)) {
				inodeno = le32_to_cpu(dir->inode);
				break;
			}

			offset += direntlen;

		} while (offset < fs->blksz);

		if (inodeno > 0) {
			free(block_buffer);
			return inodeno;
		}
	}

fail:
	free(block_buffer);

	return -1;
}

static int find_dir_depth(char *dirname)
{
	char *token = strtok(dirname, "/");
	int count = 0;
	while (token != NULL) {
		token = strtok(NULL, "/");
		count++;
	}
	return count + 1 + 1;
	/*
	 * for example  for string /home/temp
	 * depth=home(1)+temp(1)+1 extra for NULL;
	 * so count is 4;
	 */
}

static int parse_path(char **arr, char *dirname)
{
	char *token = strtok(dirname, "/");
	int i = 0;

	/* add root */
	arr[i] = zalloc(strlen("/") + 1);
	if (!arr[i])
		return -ENOMEM;
	memcpy(arr[i++], "/", strlen("/"));

	/* add each path entry after root */
	while (token != NULL) {
		arr[i] = zalloc(strlen(token) + 1);
		if (!arr[i])
			return -ENOMEM;
		memcpy(arr[i++], token, strlen(token));
		token = strtok(NULL, "/");
	}
	arr[i] = NULL;

	return 0;
}

int ext4fs_iget(int inode_no, struct ext2_inode *inode)
{
	if (ext4fs_read_inode(ext4fs_root, inode_no, inode) == 0)
		return -1;

	return 0;
}

/*
 * Function: ext4fs_get_parent_inode_num
 * Return Value: inode Number of the parent directory of  file/Directory to be
 * created
 * dirname : Input parmater, input path name of the file/directory to be created
 * dname : Output parameter, to be filled with the name of the directory
 * extracted from dirname
 */
int ext4fs_get_parent_inode_num(const char *dirname, char *dname, int flags)
{
	int i;
	int depth = 0;
	int matched_inode_no;
	int result_inode_no = -1;
	char **ptr = NULL;
	char *depth_dirname = NULL;
	char *parse_dirname = NULL;
	struct ext2_inode *parent_inode = NULL;
	struct ext2_inode *first_inode = NULL;
	struct ext2_inode temp_inode;

	/* TODO: input validation make equivalent to linux */
	depth_dirname = zalloc(strlen(dirname) + 1);
	if (!depth_dirname)
		return -ENOMEM;

	memcpy(depth_dirname, dirname, strlen(dirname));
	depth = find_dir_depth(depth_dirname);
	parse_dirname = zalloc(strlen(dirname) + 1);
	if (!parse_dirname)
		goto fail;
	memcpy(parse_dirname, dirname, strlen(dirname));

	/* allocate memory for each directory level */
	ptr = zalloc((depth) * sizeof(char *));
	if (!ptr)
		goto fail;
	if (parse_path(ptr, parse_dirname))
		goto fail;
	parent_inode = zalloc(sizeof(struct ext2_inode));
	if (!parent_inode)
		goto fail;
	first_inode = zalloc(sizeof(struct ext2_inode));
	if (!first_inode)
		goto fail;
	memcpy(parent_inode, ext4fs_root->inode, sizeof(struct ext2_inode));
	memcpy(first_inode, parent_inode, sizeof(struct ext2_inode));
	if (flags & F_FILE)
		result_inode_no = EXT2_ROOT_INO;
	for (i = 1; i < depth; i++) {
		matched_inode_no = search_dir(parent_inode, ptr[i]);
		if (matched_inode_no == -1) {
			if (ptr[i + 1] == NULL && i == 1) {
				result_inode_no = EXT2_ROOT_INO;
				goto end;
			} else {
				if (ptr[i + 1] == NULL)
					break;
				printf("Invalid path\n");
				result_inode_no = -1;
				goto fail;
			}
		} else {
			if (ptr[i + 1] != NULL) {
				memset(parent_inode, '\0',
				       sizeof(struct ext2_inode));
				if (ext4fs_iget(matched_inode_no,
						parent_inode)) {
					result_inode_no = -1;
					goto fail;
				}
				result_inode_no = matched_inode_no;
			} else {
				break;
			}
		}
	}

end:
	if (i == 1)
		matched_inode_no = search_dir(first_inode, ptr[i]);
	else
		matched_inode_no = search_dir(parent_inode, ptr[i]);

	if (matched_inode_no != -1) {
		ext4fs_iget(matched_inode_no, &temp_inode);
		if (le16_to_cpu(temp_inode.mode) & S_IFDIR) {
			printf("It is a Directory\n");
			result_inode_no = -1;
			goto fail;
		}
	}

	if (strlen(ptr[i]) > 256) {
		result_inode_no = -1;
		goto fail;
	}
	memcpy(dname, ptr[i], strlen(ptr[i]));

fail:
	free(depth_dirname);
	if (parse_dirname)
		free(parse_dirname);
	if (ptr) {
		for (i = 0; i < depth; i++) {
			if (!ptr[i])
				break;
			free(ptr[i]);
		}
		free(ptr);
	}
	if (parent_inode)
		free(parent_inode);
	if (first_inode)
		free(first_inode);

	return result_inode_no;
}

static int unlink_filename(char *filename, unsigned int blknr)
{
	int status;
	int inodeno = 0;
	int offset;
	char *block_buffer = NULL;
	struct ext2_dirent *dir = NULL;
	struct ext2_dirent *previous_dir;
	struct ext_filesystem *fs = get_fs();
	int ret = -1;
	char *direntname;

	block_buffer = zalloc(fs->blksz);
	if (!block_buffer)
		return -ENOMEM;

	/* read the directory block */
	status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0,
				fs->blksz, block_buffer);
	if (status == 0)
		goto fail;

	offset = 0;
	do {
		if (offset & 3) {
			printf("Badly aligned ext2_dirent\n");
			break;
		}

		previous_dir = dir;
		dir = (struct ext2_dirent *)(block_buffer + offset);
		direntname = (char *)(dir) + sizeof(struct ext2_dirent);

		int direntlen = le16_to_cpu(dir->direntlen);
		if (direntlen < sizeof(struct ext2_dirent))
			break;

		if (dir->inode && (strlen(filename) == dir->namelen) &&
		    (strncmp(direntname, filename, dir->namelen) == 0)) {
			inodeno = le32_to_cpu(dir->inode);
			break;
		}

		offset += direntlen;

	} while (offset < fs->blksz);

	if (inodeno > 0) {
		printf("file found, deleting\n");
		if (ext4fs_log_journal(block_buffer, blknr))
			goto fail;

		if (previous_dir) {
			/* merge dir entry with predecessor */
			uint16_t new_len;
			new_len = le16_to_cpu(previous_dir->direntlen);
			new_len += le16_to_cpu(dir->direntlen);
			previous_dir->direntlen = cpu_to_le16(new_len);
		} else {
			/* invalidate dir entry */
			dir->inode = 0;
		}
		if (ext4fs_put_metadata(block_buffer, blknr))
			goto fail;
		ret = inodeno;
	}
fail:
	free(block_buffer);

	return ret;
}

int ext4fs_filename_unlink(char *filename)
{
	int blk_idx;
	long int blknr = -1;
	int inodeno = -1;
	uint32_t directory_blocks;

	directory_blocks = le32_to_cpu(g_parent_inode->size) >>
		LOG2_BLOCK_SIZE(ext4fs_root);

	/* read the block no allocated to a file */
	for (blk_idx = 0; blk_idx < directory_blocks; blk_idx++) {
		blknr = read_allocated_block(g_parent_inode, blk_idx, NULL);
		if (blknr <= 0)
			break;
		inodeno = unlink_filename(filename, blknr);
		if (inodeno != -1)
			return inodeno;
	}

	return -1;
}

uint32_t ext4fs_get_new_blk_no(void)
{
	short i;
	short status;
	int remainder;
	unsigned int bg_idx;
	static int prev_bg_bitmap_index = -1;
	unsigned int blk_per_grp = le32_to_cpu(ext4fs_root->sblock.blocks_per_group);
	struct ext_filesystem *fs = get_fs();
	char *journal_buffer = zalloc(fs->blksz);
	char *zero_buffer = zalloc(fs->blksz);
	if (!journal_buffer || !zero_buffer)
		goto fail;

	if (fs->first_pass_bbmap == 0) {
		for (i = 0; i < fs->no_blkgrp; i++) {
			struct ext2_block_group *bgd = NULL;
			bgd = ext4fs_get_group_descriptor(fs, i);
			if (ext4fs_bg_get_free_blocks(bgd, fs)) {
				uint16_t bg_flags = ext4fs_bg_get_flags(bgd);
				uint64_t b_bitmap_blk =
					ext4fs_bg_get_block_id(bgd, fs);
				if (bg_flags & EXT4_BG_BLOCK_UNINIT) {
					memcpy(fs->blk_bmaps[i], zero_buffer,
					       fs->blksz);
					put_ext4(b_bitmap_blk * fs->blksz,
						 fs->blk_bmaps[i], fs->blksz);
					bg_flags &= ~EXT4_BG_BLOCK_UNINIT;
					ext4fs_bg_set_flags(bgd, bg_flags);
				}
				fs->curr_blkno =
				    _get_new_blk_no(fs->blk_bmaps[i]);
				if (fs->curr_blkno == -1)
					/* block bitmap is completely filled */
					continue;
				fs->curr_blkno = fs->curr_blkno +
						(i * fs->blksz * 8);
				fs->first_pass_bbmap++;
				ext4fs_bg_free_blocks_dec(bgd, fs);
				ext4fs_sb_free_blocks_dec(fs->sb);
				status = ext4fs_devread(b_bitmap_blk *
							fs->sect_perblk,
							0, fs->blksz,
							journal_buffer);
				if (status == 0)
					goto fail;
				if (ext4fs_log_journal(journal_buffer,
						       b_bitmap_blk))
					goto fail;
				goto success;
			} else {
				debug("no space left on block group %d\n", i);
			}
		}

		goto fail;
	} else {
		fs->curr_blkno++;
restart:
		/* get the blockbitmap index respective to blockno */
		bg_idx = fs->curr_blkno / blk_per_grp;
		if (fs->blksz == 1024) {
			remainder = fs->curr_blkno % blk_per_grp;
			if (!remainder)
				bg_idx--;
		}

		/*
		 * To skip completely filled block group bitmaps
		 * Optimize the block allocation
		 */
		if (bg_idx >= fs->no_blkgrp)
			goto fail;

		struct ext2_block_group *bgd = NULL;
		bgd = ext4fs_get_group_descriptor(fs, bg_idx);
		if (ext4fs_bg_get_free_blocks(bgd, fs) == 0) {
			debug("block group %u is full. Skipping\n", bg_idx);
			fs->curr_blkno = (bg_idx + 1) * blk_per_grp;
			if (fs->blksz == 1024)
				fs->curr_blkno += 1;
			goto restart;
		}

		uint16_t bg_flags = ext4fs_bg_get_flags(bgd);
		uint64_t b_bitmap_blk = ext4fs_bg_get_block_id(bgd, fs);
		if (bg_flags & EXT4_BG_BLOCK_UNINIT) {
			memcpy(fs->blk_bmaps[bg_idx], zero_buffer, fs->blksz);
			put_ext4(b_bitmap_blk * fs->blksz,
				 zero_buffer, fs->blksz);
			bg_flags &= ~EXT4_BG_BLOCK_UNINIT;
			ext4fs_bg_set_flags(bgd, bg_flags);
		}

		if (ext4fs_set_block_bmap(fs->curr_blkno, fs->blk_bmaps[bg_idx],
				   bg_idx) != 0) {
			debug("going for restart for the block no %ld %u\n",
			      fs->curr_blkno, bg_idx);
			fs->curr_blkno++;
			goto restart;
		}

		/* journal backup */
		if (prev_bg_bitmap_index != bg_idx) {
			status = ext4fs_devread(b_bitmap_blk * fs->sect_perblk,
						0, fs->blksz, journal_buffer);
			if (status == 0)
				goto fail;
			if (ext4fs_log_journal(journal_buffer, b_bitmap_blk))
				goto fail;

			prev_bg_bitmap_index = bg_idx;
		}
		ext4fs_bg_free_blocks_dec(bgd, fs);
		ext4fs_sb_free_blocks_dec(fs->sb);
		goto success;
	}
success:
	free(journal_buffer);
	free(zero_buffer);

	return fs->curr_blkno;
fail:
	free(journal_buffer);
	free(zero_buffer);

	return -1;
}

int ext4fs_get_new_inode_no(void)
{
	short i;
	short status;
	unsigned int ibmap_idx;
	static int prev_inode_bitmap_index = -1;
	unsigned int inodes_per_grp = le32_to_cpu(ext4fs_root->sblock.inodes_per_group);
	struct ext_filesystem *fs = get_fs();
	char *journal_buffer = zalloc(fs->blksz);
	char *zero_buffer = zalloc(fs->blksz);
	if (!journal_buffer || !zero_buffer)
		goto fail;
	int has_gdt_chksum = le32_to_cpu(fs->sb->feature_ro_compat) &
		EXT4_FEATURE_RO_COMPAT_GDT_CSUM ? 1 : 0;

	if (fs->first_pass_ibmap == 0) {
		for (i = 0; i < fs->no_blkgrp; i++) {
			uint32_t free_inodes;
			struct ext2_block_group *bgd = NULL;
			bgd = ext4fs_get_group_descriptor(fs, i);
			free_inodes = ext4fs_bg_get_free_inodes(bgd, fs);
			if (free_inodes) {
				uint16_t bg_flags = ext4fs_bg_get_flags(bgd);
				uint64_t i_bitmap_blk =
					ext4fs_bg_get_inode_id(bgd, fs);
				if (has_gdt_chksum)
					bgd->bg_itable_unused = free_inodes;
				if (bg_flags & EXT4_BG_INODE_UNINIT) {
					put_ext4(i_bitmap_blk * fs->blksz,
						 zero_buffer, fs->blksz);
					bg_flags &= ~EXT4_BG_INODE_UNINIT;
					ext4fs_bg_set_flags(bgd, bg_flags);
					memcpy(fs->inode_bmaps[i],
					       zero_buffer, fs->blksz);
				}
				fs->curr_inode_no =
				    _get_new_inode_no(fs->inode_bmaps[i]);
				if (fs->curr_inode_no == -1)
					/* inode bitmap is completely filled */
					continue;
				fs->curr_inode_no = fs->curr_inode_no +
							(i * inodes_per_grp);
				fs->first_pass_ibmap++;
				ext4fs_bg_free_inodes_dec(bgd, fs);
				if (has_gdt_chksum)
					ext4fs_bg_itable_unused_dec(bgd, fs);
				ext4fs_sb_free_inodes_dec(fs->sb);
				status = ext4fs_devread(i_bitmap_blk *
							fs->sect_perblk,
							0, fs->blksz,
							journal_buffer);
				if (status == 0)
					goto fail;
				if (ext4fs_log_journal(journal_buffer,
						       i_bitmap_blk))
					goto fail;
				goto success;
			} else
				debug("no inode left on block group %d\n", i);
		}
		goto fail;
	} else {
restart:
		fs->curr_inode_no++;
		/* get the blockbitmap index respective to blockno */
		ibmap_idx = fs->curr_inode_no / inodes_per_grp;
		struct ext2_block_group *bgd =
			ext4fs_get_group_descriptor(fs, ibmap_idx);
		uint16_t bg_flags = ext4fs_bg_get_flags(bgd);
		uint64_t i_bitmap_blk = ext4fs_bg_get_inode_id(bgd, fs);

		if (bg_flags & EXT4_BG_INODE_UNINIT) {
			put_ext4(i_bitmap_blk * fs->blksz,
				 zero_buffer, fs->blksz);
			bg_flags &= ~EXT4_BG_INODE_UNINIT;
			ext4fs_bg_set_flags(bgd, bg_flags);
			memcpy(fs->inode_bmaps[ibmap_idx], zero_buffer,
				fs->blksz);
		}

		if (ext4fs_set_inode_bmap(fs->curr_inode_no,
					  fs->inode_bmaps[ibmap_idx],
					  ibmap_idx) != 0) {
			debug("going for restart for the block no %d %u\n",
			      fs->curr_inode_no, ibmap_idx);
			goto restart;
		}

		/* journal backup */
		if (prev_inode_bitmap_index != ibmap_idx) {
			status = ext4fs_devread(i_bitmap_blk * fs->sect_perblk,
						0, fs->blksz, journal_buffer);
			if (status == 0)
				goto fail;
			if (ext4fs_log_journal(journal_buffer,
						le32_to_cpu(bgd->inode_id)))
				goto fail;
			prev_inode_bitmap_index = ibmap_idx;
		}
		ext4fs_bg_free_inodes_dec(bgd, fs);
		if (has_gdt_chksum)
			bgd->bg_itable_unused = bgd->free_inodes;
		ext4fs_sb_free_inodes_dec(fs->sb);
		goto success;
	}

success:
	free(journal_buffer);
	free(zero_buffer);

	return fs->curr_inode_no;
fail:
	free(journal_buffer);
	free(zero_buffer);

	return -1;

}


static void alloc_single_indirect_block(struct ext2_inode *file_inode,
					unsigned int *total_remaining_blocks,
					unsigned int *no_blks_reqd)
{
	short i;
	short status;
	long int actual_block_no;
	long int si_blockno;
	/* si :single indirect */
	__le32 *si_buffer = NULL;
	__le32 *si_start_addr = NULL;
	struct ext_filesystem *fs = get_fs();

	if (*total_remaining_blocks != 0) {
		si_buffer = zalloc(fs->blksz);
		if (!si_buffer) {
			printf("No Memory\n");
			return;
		}
		si_start_addr = si_buffer;
		si_blockno = ext4fs_get_new_blk_no();
		if (si_blockno == -1) {
			printf("no block left to assign\n");
			goto fail;
		}
		(*no_blks_reqd)++;
		debug("SIPB %ld: %u\n", si_blockno, *total_remaining_blocks);

		status = ext4fs_devread((lbaint_t)si_blockno * fs->sect_perblk,
					0, fs->blksz, (char *)si_buffer);
		memset(si_buffer, '\0', fs->blksz);
		if (status == 0)
			goto fail;

		for (i = 0; i < (fs->blksz / sizeof(int)); i++) {
			actual_block_no = ext4fs_get_new_blk_no();
			if (actual_block_no == -1) {
				printf("no block left to assign\n");
				goto fail;
			}
			*si_buffer = cpu_to_le32(actual_block_no);
			debug("SIAB %u: %u\n", *si_buffer,
				*total_remaining_blocks);

			si_buffer++;
			(*total_remaining_blocks)--;
			if (*total_remaining_blocks == 0)
				break;
		}

		/* write the block to disk */
		put_ext4(((uint64_t) ((uint64_t)si_blockno * (uint64_t)fs->blksz)),
			 si_start_addr, fs->blksz);
		file_inode->b.blocks.indir_block = cpu_to_le32(si_blockno);
	}
fail:
	free(si_start_addr);
}

static void alloc_double_indirect_block(struct ext2_inode *file_inode,
					unsigned int *total_remaining_blocks,
					unsigned int *no_blks_reqd)
{
	short i;
	short j;
	short status;
	long int actual_block_no;
	/* di:double indirect */
	long int di_blockno_parent;
	long int di_blockno_child;
	__le32 *di_parent_buffer = NULL;
	__le32 *di_child_buff = NULL;
	__le32 *di_block_start_addr = NULL;
	__le32 *di_child_buff_start = NULL;
	struct ext_filesystem *fs = get_fs();

	if (*total_remaining_blocks != 0) {
		/* double indirect parent block connecting to inode */
		di_blockno_parent = ext4fs_get_new_blk_no();
		if (di_blockno_parent == -1) {
			printf("no block left to assign\n");
			goto fail;
		}
		di_parent_buffer = zalloc(fs->blksz);
		if (!di_parent_buffer)
			goto fail;

		di_block_start_addr = di_parent_buffer;
		(*no_blks_reqd)++;
		debug("DIPB %ld: %u\n", di_blockno_parent,
		      *total_remaining_blocks);

		status = ext4fs_devread((lbaint_t)di_blockno_parent *
					fs->sect_perblk, 0,
					fs->blksz, (char *)di_parent_buffer);

		if (!status) {
			printf("%s: Device read error!\n", __func__);
			goto fail;
		}
		memset(di_parent_buffer, '\0', fs->blksz);

		/*
		 * start:for each double indirect parent
		 * block create one more block
		 */
		for (i = 0; i < (fs->blksz / sizeof(int)); i++) {
			di_blockno_child = ext4fs_get_new_blk_no();
			if (di_blockno_child == -1) {
				printf("no block left to assign\n");
				goto fail;
			}
			di_child_buff = zalloc(fs->blksz);
			if (!di_child_buff)
				goto fail;

			di_child_buff_start = di_child_buff;
			*di_parent_buffer = cpu_to_le32(di_blockno_child);
			di_parent_buffer++;
			(*no_blks_reqd)++;
			debug("DICB %ld: %u\n", di_blockno_child,
			      *total_remaining_blocks);

			status = ext4fs_devread((lbaint_t)di_blockno_child *
						fs->sect_perblk, 0,
						fs->blksz,
						(char *)di_child_buff);

			if (!status) {
				printf("%s: Device read error!\n", __func__);
				goto fail;
			}
			memset(di_child_buff, '\0', fs->blksz);
			/* filling of actual datablocks for each child */
			for (j = 0; j < (fs->blksz / sizeof(int)); j++) {
				actual_block_no = ext4fs_get_new_blk_no();
				if (actual_block_no == -1) {
					printf("no block left to assign\n");
					goto fail;
				}
				*di_child_buff = cpu_to_le32(actual_block_no);
				debug("DIAB %ld: %u\n", actual_block_no,
				      *total_remaining_blocks);

				di_child_buff++;
				(*total_remaining_blocks)--;
				if (*total_remaining_blocks == 0)
					break;
			}
			/* write the block  table */
			put_ext4(((uint64_t) ((uint64_t)di_blockno_child * (uint64_t)fs->blksz)),
				 di_child_buff_start, fs->blksz);
			free(di_child_buff_start);
			di_child_buff_start = NULL;

			if (*total_remaining_blocks == 0)
				break;
		}
		put_ext4(((uint64_t) ((uint64_t)di_blockno_parent * (uint64_t)fs->blksz)),
			 di_block_start_addr, fs->blksz);
		file_inode->b.blocks.double_indir_block = cpu_to_le32(di_blockno_parent);
	}
fail:
	free(di_block_start_addr);
}

static void alloc_triple_indirect_block(struct ext2_inode *file_inode,
					unsigned int *total_remaining_blocks,
					unsigned int *no_blks_reqd)
{
	short i;
	short j;
	short k;
	long int actual_block_no;
	/* ti: Triple Indirect */
	long int ti_gp_blockno;
	long int ti_parent_blockno;
	long int ti_child_blockno;
	__le32 *ti_gp_buff = NULL;
	__le32 *ti_parent_buff = NULL;
	__le32 *ti_child_buff = NULL;
	__le32 *ti_gp_buff_start_addr = NULL;
	__le32 *ti_pbuff_start_addr = NULL;
	__le32 *ti_cbuff_start_addr = NULL;
	struct ext_filesystem *fs = get_fs();
	if (*total_remaining_blocks != 0) {
		/* triple indirect grand parent block connecting to inode */
		ti_gp_blockno = ext4fs_get_new_blk_no();
		if (ti_gp_blockno == -1) {
			printf("no block left to assign\n");
			return;
		}
		ti_gp_buff = zalloc(fs->blksz);
		if (!ti_gp_buff)
			return;

		ti_gp_buff_start_addr = ti_gp_buff;
		(*no_blks_reqd)++;
		debug("TIGPB %ld: %u\n", ti_gp_blockno,
		      *total_remaining_blocks);

		/* for each 4 byte grand parent entry create one more block */
		for (i = 0; i < (fs->blksz / sizeof(int)); i++) {
			ti_parent_blockno = ext4fs_get_new_blk_no();
			if (ti_parent_blockno == -1) {
				printf("no block left to assign\n");
				goto fail;
			}
			ti_parent_buff = zalloc(fs->blksz);
			if (!ti_parent_buff)
				goto fail;

			ti_pbuff_start_addr = ti_parent_buff;
			*ti_gp_buff = cpu_to_le32(ti_parent_blockno);
			ti_gp_buff++;
			(*no_blks_reqd)++;
			debug("TIPB %ld: %u\n", ti_parent_blockno,
			      *total_remaining_blocks);

			/* for each 4 byte entry parent create one more block */
			for (j = 0; j < (fs->blksz / sizeof(int)); j++) {
				ti_child_blockno = ext4fs_get_new_blk_no();
				if (ti_child_blockno == -1) {
					printf("no block left assign\n");
					goto fail1;
				}
				ti_child_buff = zalloc(fs->blksz);
				if (!ti_child_buff)
					goto fail1;

				ti_cbuff_start_addr = ti_child_buff;
				*ti_parent_buff = cpu_to_le32(ti_child_blockno);
				ti_parent_buff++;
				(*no_blks_reqd)++;
				debug("TICB %ld: %u\n", ti_parent_blockno,
				      *total_remaining_blocks);

				/* fill actual datablocks for each child */
				for (k = 0; k < (fs->blksz / sizeof(int));
					k++) {
					actual_block_no =
					    ext4fs_get_new_blk_no();
					if (actual_block_no == -1) {
						printf("no block left\n");
						free(ti_cbuff_start_addr);
						goto fail1;
					}
					*ti_child_buff = cpu_to_le32(actual_block_no);
					debug("TIAB %ld: %u\n", actual_block_no,
					      *total_remaining_blocks);

					ti_child_buff++;
					(*total_remaining_blocks)--;
					if (*total_remaining_blocks == 0)
						break;
				}
				/* write the child block */
				put_ext4(((uint64_t) ((uint64_t)ti_child_blockno *
						      (uint64_t)fs->blksz)),
					 ti_cbuff_start_addr, fs->blksz);
				free(ti_cbuff_start_addr);

				if (*total_remaining_blocks == 0)
					break;
			}
			/* write the parent block */
			put_ext4(((uint64_t) ((uint64_t)ti_parent_blockno * (uint64_t)fs->blksz)),
				 ti_pbuff_start_addr, fs->blksz);
			free(ti_pbuff_start_addr);

			if (*total_remaining_blocks == 0)
				break;
		}
		/* write the grand parent block */
		put_ext4(((uint64_t) ((uint64_t)ti_gp_blockno * (uint64_t)fs->blksz)),
			 ti_gp_buff_start_addr, fs->blksz);
		file_inode->b.blocks.triple_indir_block = cpu_to_le32(ti_gp_blockno);
		free(ti_gp_buff_start_addr);
		return;
	}
fail1:
	free(ti_pbuff_start_addr);
fail:
	free(ti_gp_buff_start_addr);
}

void ext4fs_allocate_blocks(struct ext2_inode *file_inode,
				unsigned int total_remaining_blocks,
				unsigned int *total_no_of_block)
{
	short i;
	long int direct_blockno;
	unsigned int no_blks_reqd = 0;

	/* allocation of direct blocks */
	for (i = 0; total_remaining_blocks && i < INDIRECT_BLOCKS; i++) {
		direct_blockno = ext4fs_get_new_blk_no();
		if (direct_blockno == -1) {
			printf("no block left to assign\n");
			return;
		}
		file_inode->b.blocks.dir_blocks[i] = cpu_to_le32(direct_blockno);
		debug("DB %ld: %u\n", direct_blockno, total_remaining_blocks);

		total_remaining_blocks--;
	}

	alloc_single_indirect_block(file_inode, &total_remaining_blocks,
				    &no_blks_reqd);
	alloc_double_indirect_block(file_inode, &total_remaining_blocks,
				    &no_blks_reqd);
	alloc_triple_indirect_block(file_inode, &total_remaining_blocks,
				    &no_blks_reqd);
	*total_no_of_block += no_blks_reqd;
}

#endif

static struct ext4_extent_header *ext4fs_get_extent_block
	(struct ext2_data *data, struct ext_block_cache *cache,
		struct ext4_extent_header *ext_block,
		uint32_t fileblock, int log2_blksz)
{
	struct ext4_extent_idx *index;
	unsigned long long block;
	int blksz = EXT2_BLOCK_SIZE(data);
	int i;

	while (1) {
		index = (struct ext4_extent_idx *)(ext_block + 1);

		if (le16_to_cpu(ext_block->eh_magic) != EXT4_EXT_MAGIC)
			return NULL;

		if (ext_block->eh_depth == 0)
			return ext_block;
		i = -1;
		do {
			i++;
			if (i >= le16_to_cpu(ext_block->eh_entries))
				break;
		} while (fileblock >= le32_to_cpu(index[i].ei_block));

		/*
		 * If first logical block number is higher than requested fileblock,
		 * it is a sparse file. This is handled on upper layer.
		 */
		if (i > 0)
			i--;

		block = le16_to_cpu(index[i].ei_leaf_hi);
		block = (block << 32) + le32_to_cpu(index[i].ei_leaf_lo);
		block <<= log2_blksz;
		if (!ext_cache_read(cache, (lbaint_t)block, blksz))
			return NULL;
		ext_block = (struct ext4_extent_header *)cache->buf;
	}
}

static int ext4fs_blockgroup
	(struct ext2_data *data, int group, struct ext2_block_group *blkgrp)
{
	long int blkno;
	unsigned int blkoff, desc_per_blk;
	int log2blksz = get_fs()->dev_desc->log2blksz;
	int desc_size = get_fs()->gdsize;

	if (desc_size == 0)
		return 0;
	desc_per_blk = EXT2_BLOCK_SIZE(data) / desc_size;

	if (desc_per_blk == 0)
		return 0;
	blkno = le32_to_cpu(data->sblock.first_data_block) + 1 +
			group / desc_per_blk;
	blkoff = (group % desc_per_blk) * desc_size;

	debug("ext4fs read %d group descriptor (blkno %ld blkoff %u)\n",
	      group, blkno, blkoff);

	return ext4fs_devread((lbaint_t)blkno <<
			      (LOG2_BLOCK_SIZE(data) - log2blksz),
			      blkoff, desc_size, (char *)blkgrp);
}

int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode)
{
	struct ext2_block_group *blkgrp;
	struct ext2_sblock *sblock = &data->sblock;
	struct ext_filesystem *fs = get_fs();
	int log2blksz = get_fs()->dev_desc->log2blksz;
	int inodes_per_block, status;
	long int blkno;
	unsigned int blkoff;

	/* Allocate blkgrp based on gdsize (for 64-bit support). */
	blkgrp = zalloc(get_fs()->gdsize);
	if (!blkgrp)
		return 0;

	/* It is easier to calculate if the first inode is 0. */
	ino--;
	if ( le32_to_cpu(sblock->inodes_per_group) == 0 || fs->inodesz == 0) {
		free(blkgrp);
		return 0;
	}
	status = ext4fs_blockgroup(data, ino / le32_to_cpu
				   (sblock->inodes_per_group), blkgrp);
	if (status == 0) {
		free(blkgrp);
		return 0;
	}

	inodes_per_block = EXT2_BLOCK_SIZE(data) / fs->inodesz;
	if ( inodes_per_block == 0 ) {
		free(blkgrp);
		return 0;
	}
	blkno = ext4fs_bg_get_inode_table_id(blkgrp, fs) +
	    (ino % le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block;
	blkoff = (ino % inodes_per_block) * fs->inodesz;

	/* Free blkgrp as it is no longer required. */
	free(blkgrp);

	/* Read the inode. */
	status = ext4fs_devread((lbaint_t)blkno << (LOG2_BLOCK_SIZE(data) -
				log2blksz), blkoff,
				sizeof(struct ext2_inode), (char *)inode);
	if (status == 0)
		return 0;

	return 1;
}

long int read_allocated_block(struct ext2_inode *inode, int fileblock,
			      struct ext_block_cache *cache)
{
	long int blknr;
	int blksz;
	int log2_blksz;
	int status;
	long int rblock;
	long int perblock_parent;
	long int perblock_child;
	unsigned long long start;
	/* get the blocksize of the filesystem */
	blksz = EXT2_BLOCK_SIZE(ext4fs_root);
	log2_blksz = LOG2_BLOCK_SIZE(ext4fs_root)
		- get_fs()->dev_desc->log2blksz;

	if (le32_to_cpu(inode->flags) & EXT4_EXTENTS_FL) {
		long int startblock, endblock;
		struct ext_block_cache *c, cd;
		struct ext4_extent_header *ext_block;
		struct ext4_extent *extent;
		int i;

		if (cache) {
			c = cache;
		} else {
			c = &cd;
			ext_cache_init(c);
		}
		ext_block =
			ext4fs_get_extent_block(ext4fs_root, c,
						(struct ext4_extent_header *)
						inode->b.blocks.dir_blocks,
						fileblock, log2_blksz);
		if (!ext_block) {
			printf("invalid extent block\n");
			if (!cache)
				ext_cache_fini(c);
			return -EINVAL;
		}

		extent = (struct ext4_extent *)(ext_block + 1);

		for (i = 0; i < le16_to_cpu(ext_block->eh_entries); i++) {
			startblock = le32_to_cpu(extent[i].ee_block);
			endblock = startblock + le16_to_cpu(extent[i].ee_len);

			if (startblock > fileblock) {
				/* Sparse file */
				if (!cache)
					ext_cache_fini(c);
				return 0;

			} else if (fileblock < endblock) {
				start = le16_to_cpu(extent[i].ee_start_hi);
				start = (start << 32) +
					le32_to_cpu(extent[i].ee_start_lo);
				if (!cache)
					ext_cache_fini(c);
				return (fileblock - startblock) + start;
			}
		}

		if (!cache)
			ext_cache_fini(c);
		return 0;
	}

	/* Direct blocks. */
	if (fileblock < INDIRECT_BLOCKS)
		blknr = le32_to_cpu(inode->b.blocks.dir_blocks[fileblock]);

	/* Indirect. */
	else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4))) {
		if (ext4fs_indir1_block == NULL) {
			ext4fs_indir1_block = zalloc(blksz);
			if (ext4fs_indir1_block == NULL) {
				printf("** SI ext2fs read block (indir 1)"
					"malloc failed. **\n");
				return -1;
			}
			ext4fs_indir1_size = blksz;
			ext4fs_indir1_blkno = -1;
		}
		if (blksz != ext4fs_indir1_size) {
			free(ext4fs_indir1_block);
			ext4fs_indir1_block = NULL;
			ext4fs_indir1_size = 0;
			ext4fs_indir1_blkno = -1;
			ext4fs_indir1_block = zalloc(blksz);
			if (ext4fs_indir1_block == NULL) {
				printf("** SI ext2fs read block (indir 1):"
					"malloc failed. **\n");
				return -1;
			}
			ext4fs_indir1_size = blksz;
		}
		if ((le32_to_cpu(inode->b.blocks.indir_block) <<
		     log2_blksz) != ext4fs_indir1_blkno) {
			status =
			    ext4fs_devread((lbaint_t)le32_to_cpu
					   (inode->b.blocks.
					    indir_block) << log2_blksz, 0,
					   blksz, (char *)ext4fs_indir1_block);
			if (status == 0) {
				printf("** SI ext2fs read block (indir 1)"
					"failed. **\n");
				return -1;
			}
			ext4fs_indir1_blkno =
				le32_to_cpu(inode->b.blocks.
					       indir_block) << log2_blksz;
		}
		blknr = le32_to_cpu(ext4fs_indir1_block
				      [fileblock - INDIRECT_BLOCKS]);
	}
	/* Double indirect. */
	else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4 *
					(blksz / 4 + 1)))) {

		long int perblock = blksz / 4;
		long int rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4);

		if (ext4fs_indir1_block == NULL) {
			ext4fs_indir1_block = zalloc(blksz);
			if (ext4fs_indir1_block == NULL) {
				printf("** DI ext2fs read block (indir 2 1)"
					"malloc failed. **\n");
				return -1;
			}
			ext4fs_indir1_size = blksz;
			ext4fs_indir1_blkno = -1;
		}
		if (blksz != ext4fs_indir1_size) {
			free(ext4fs_indir1_block);
			ext4fs_indir1_block = NULL;
			ext4fs_indir1_size = 0;
			ext4fs_indir1_blkno = -1;
			ext4fs_indir1_block = zalloc(blksz);
			if (ext4fs_indir1_block == NULL) {
				printf("** DI ext2fs read block (indir 2 1)"
					"malloc failed. **\n");
				return -1;
			}
			ext4fs_indir1_size = blksz;
		}
		if ((le32_to_cpu(inode->b.blocks.double_indir_block) <<
		     log2_blksz) != ext4fs_indir1_blkno) {
			status =
			    ext4fs_devread((lbaint_t)le32_to_cpu
					   (inode->b.blocks.
					    double_indir_block) << log2_blksz,
					   0, blksz,
					   (char *)ext4fs_indir1_block);
			if (status == 0) {
				printf("** DI ext2fs read block (indir 2 1)"
					"failed. **\n");
				return -1;
			}
			ext4fs_indir1_blkno =
			    le32_to_cpu(inode->b.blocks.double_indir_block) <<
			    log2_blksz;
		}

		if (ext4fs_indir2_block == NULL) {
			ext4fs_indir2_block = zalloc(blksz);
			if (ext4fs_indir2_block == NULL) {
				printf("** DI ext2fs read block (indir 2 2)"
					"malloc failed. **\n");
				return -1;
			}
			ext4fs_indir2_size = blksz;
			ext4fs_indir2_blkno = -1;
		}
		if (blksz != ext4fs_indir2_size) {
			free(ext4fs_indir2_block);
			ext4fs_indir2_block = NULL;
			ext4fs_indir2_size = 0;
			ext4fs_indir2_blkno = -1;
			ext4fs_indir2_block = zalloc(blksz);
			if (ext4fs_indir2_block == NULL) {
				printf("** DI ext2fs read block (indir 2 2)"
					"malloc failed. **\n");
				return -1;
			}
			ext4fs_indir2_size = blksz;
		}
		if ((le32_to_cpu(ext4fs_indir1_block[rblock / perblock]) <<
		     log2_blksz) != ext4fs_indir2_blkno) {
			status = ext4fs_devread((lbaint_t)le32_to_cpu
						(ext4fs_indir1_block
						 [rblock /
						  perblock]) << log2_blksz, 0,
						blksz,
						(char *)ext4fs_indir2_block);
			if (status == 0) {
				printf("** DI ext2fs read block (indir 2 2)"
					"failed. **\n");
				return -1;
			}
			ext4fs_indir2_blkno =
			    le32_to_cpu(ext4fs_indir1_block[rblock
							      /
							      perblock]) <<
			    log2_blksz;
		}
		blknr = le32_to_cpu(ext4fs_indir2_block[rblock % perblock]);
	}
	/* Tripple indirect. */
	else {
		rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4 +
				      (blksz / 4 * blksz / 4));
		perblock_child = blksz / 4;
		perblock_parent = ((blksz / 4) * (blksz / 4));

		if (ext4fs_indir1_block == NULL) {
			ext4fs_indir1_block = zalloc(blksz);
			if (ext4fs_indir1_block == NULL) {
				printf("** TI ext2fs read block (indir 2 1)"
					"malloc failed. **\n");
				return -1;
			}
			ext4fs_indir1_size = blksz;
			ext4fs_indir1_blkno = -1;
		}
		if (blksz != ext4fs_indir1_size) {
			free(ext4fs_indir1_block);
			ext4fs_indir1_block = NULL;
			ext4fs_indir1_size = 0;
			ext4fs_indir1_blkno = -1;
			ext4fs_indir1_block = zalloc(blksz);
			if (ext4fs_indir1_block == NULL) {
				printf("** TI ext2fs read block (indir 2 1)"
					"malloc failed. **\n");
				return -1;
			}
			ext4fs_indir1_size = blksz;
		}
		if ((le32_to_cpu(inode->b.blocks.triple_indir_block) <<
		     log2_blksz) != ext4fs_indir1_blkno) {
			status = ext4fs_devread
			    ((lbaint_t)
			     le32_to_cpu(inode->b.blocks.triple_indir_block)
			     << log2_blksz, 0, blksz,
			     (char *)ext4fs_indir1_block);
			if (status == 0) {
				printf("** TI ext2fs read block (indir 2 1)"
					"failed. **\n");
				return -1;
			}
			ext4fs_indir1_blkno =
			    le32_to_cpu(inode->b.blocks.triple_indir_block) <<
			    log2_blksz;
		}

		if (ext4fs_indir2_block == NULL) {
			ext4fs_indir2_block = zalloc(blksz);
			if (ext4fs_indir2_block == NULL) {
				printf("** TI ext2fs read block (indir 2 2)"
					"malloc failed. **\n");
				return -1;
			}
			ext4fs_indir2_size = blksz;
			ext4fs_indir2_blkno = -1;
		}
		if (blksz != ext4fs_indir2_size) {
			free(ext4fs_indir2_block);
			ext4fs_indir2_block = NULL;
			ext4fs_indir2_size = 0;
			ext4fs_indir2_blkno = -1;
			ext4fs_indir2_block = zalloc(blksz);
			if (ext4fs_indir2_block == NULL) {
				printf("** TI ext2fs read block (indir 2 2)"
					"malloc failed. **\n");
				return -1;
			}
			ext4fs_indir2_size = blksz;
		}
		if ((le32_to_cpu(ext4fs_indir1_block[rblock /
						       perblock_parent]) <<
		     log2_blksz)
		    != ext4fs_indir2_blkno) {
			status = ext4fs_devread((lbaint_t)le32_to_cpu
						(ext4fs_indir1_block
						 [rblock /
						  perblock_parent]) <<
						log2_blksz, 0, blksz,
						(char *)ext4fs_indir2_block);
			if (status == 0) {
				printf("** TI ext2fs read block (indir 2 2)"
					"failed. **\n");
				return -1;
			}
			ext4fs_indir2_blkno =
			    le32_to_cpu(ext4fs_indir1_block[rblock /
							      perblock_parent])
			    << log2_blksz;
		}

		if (ext4fs_indir3_block == NULL) {
			ext4fs_indir3_block = zalloc(blksz);
			if (ext4fs_indir3_block == NULL) {
				printf("** TI ext2fs read block (indir 2 2)"
					"malloc failed. **\n");
				return -1;
			}
			ext4fs_indir3_size = blksz;
			ext4fs_indir3_blkno = -1;
		}
		if (blksz != ext4fs_indir3_size) {
			free(ext4fs_indir3_block);
			ext4fs_indir3_block = NULL;
			ext4fs_indir3_size = 0;
			ext4fs_indir3_blkno = -1;
			ext4fs_indir3_block = zalloc(blksz);
			if (ext4fs_indir3_block == NULL) {
				printf("** TI ext2fs read block (indir 2 2)"
					"malloc failed. **\n");
				return -1;
			}
			ext4fs_indir3_size = blksz;
		}
		if ((le32_to_cpu(ext4fs_indir2_block[rblock
						       /
						       perblock_child]) <<
		     log2_blksz) != ext4fs_indir3_blkno) {
			status =
			    ext4fs_devread((lbaint_t)le32_to_cpu
					   (ext4fs_indir2_block
					    [(rblock / perblock_child)
					     % (blksz / 4)]) << log2_blksz, 0,
					   blksz, (char *)ext4fs_indir3_block);
			if (status == 0) {
				printf("** TI ext2fs read block (indir 2 2)"
				       "failed. **\n");
				return -1;
			}
			ext4fs_indir3_blkno =
			    le32_to_cpu(ext4fs_indir2_block[(rblock /
							       perblock_child) %
							      (blksz /
							       4)]) <<
			    log2_blksz;
		}

		blknr = le32_to_cpu(ext4fs_indir3_block
				      [rblock % perblock_child]);
	}
	debug("read_allocated_block %ld\n", blknr);

	return blknr;
}

/**
 * ext4fs_reinit_global() - Reinitialize values of ext4 write implementation's
 *			    global pointers
 *
 * This function assures that for a file with the same name but different size
 * the sequential store on the ext4 filesystem will be correct.
 *
 * In this function the global data, responsible for internal representation
 * of the ext4 data are initialized to the reset state. Without this, during
 * replacement of the smaller file with the bigger truncation of new file was
 * performed.
 */
void ext4fs_reinit_global(void)
{
	if (ext4fs_indir1_block != NULL) {
		free(ext4fs_indir1_block);
		ext4fs_indir1_block = NULL;
		ext4fs_indir1_size = 0;
		ext4fs_indir1_blkno = -1;
	}
	if (ext4fs_indir2_block != NULL) {
		free(ext4fs_indir2_block);
		ext4fs_indir2_block = NULL;
		ext4fs_indir2_size = 0;
		ext4fs_indir2_blkno = -1;
	}
	if (ext4fs_indir3_block != NULL) {
		free(ext4fs_indir3_block);
		ext4fs_indir3_block = NULL;
		ext4fs_indir3_size = 0;
		ext4fs_indir3_blkno = -1;
	}
}
void ext4fs_close(void)
{
	if ((ext4fs_file != NULL) && (ext4fs_root != NULL)) {
		ext4fs_free_node(ext4fs_file, &ext4fs_root->diropen);
		ext4fs_file = NULL;
	}
	if (ext4fs_root != NULL) {
		free(ext4fs_root);
		ext4fs_root = NULL;
	}

	ext4fs_reinit_global();
}

int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,
				struct ext2fs_node **fnode, int *ftype)
{
	unsigned int fpos = 0;
	int status;
	loff_t actread;
	struct ext2fs_node *diro = (struct ext2fs_node *) dir;

#ifdef DEBUG
	if (name != NULL)
		printf("Iterate dir %s\n", name);
#endif /* of DEBUG */
	if (!diro->inode_read) {
		status = ext4fs_read_inode(diro->data, diro->ino, &diro->inode);
		if (status == 0)
			return 0;
	}
	/* Search the file.  */
	while (fpos < le32_to_cpu(diro->inode.size)) {
		struct ext2_dirent dirent;

		status = ext4fs_read_file(diro, fpos,
					   sizeof(struct ext2_dirent),
					   (char *)&dirent, &actread);
		if (status < 0)
			return 0;

		if (dirent.direntlen == 0) {
			printf("Failed to iterate over directory %s\n", name);
			return 0;
		}

		if (dirent.namelen != 0) {
			char filename[dirent.namelen + 1];
			struct ext2fs_node *fdiro;
			int type = FILETYPE_UNKNOWN;

			status = ext4fs_read_file(diro,
						  fpos +
						  sizeof(struct ext2_dirent),
						  dirent.namelen, filename,
						  &actread);
			if (status < 0)
				return 0;

			fdiro = zalloc(sizeof(struct ext2fs_node));
			if (!fdiro)
				return 0;

			fdiro->data = diro->data;
			fdiro->ino = le32_to_cpu(dirent.inode);

			filename[dirent.namelen] = '\0';

			if (dirent.filetype != FILETYPE_UNKNOWN) {
				fdiro->inode_read = 0;

				if (dirent.filetype == FILETYPE_DIRECTORY)
					type = FILETYPE_DIRECTORY;
				else if (dirent.filetype == FILETYPE_SYMLINK)
					type = FILETYPE_SYMLINK;
				else if (dirent.filetype == FILETYPE_REG)
					type = FILETYPE_REG;
			} else {
				status = ext4fs_read_inode(diro->data,
							   le32_to_cpu
							   (dirent.inode),
							   &fdiro->inode);
				if (status == 0) {
					free(fdiro);
					return 0;
				}
				fdiro->inode_read = 1;

				if ((le16_to_cpu(fdiro->inode.mode) &
				     FILETYPE_INO_MASK) ==
				    FILETYPE_INO_DIRECTORY) {
					type = FILETYPE_DIRECTORY;
				} else if ((le16_to_cpu(fdiro->inode.mode)
					    & FILETYPE_INO_MASK) ==
					   FILETYPE_INO_SYMLINK) {
					type = FILETYPE_SYMLINK;
				} else if ((le16_to_cpu(fdiro->inode.mode)
					    & FILETYPE_INO_MASK) ==
					   FILETYPE_INO_REG) {
					type = FILETYPE_REG;
				}
			}
#ifdef DEBUG
			printf("iterate >%s<\n", filename);
#endif /* of DEBUG */
			if ((name != NULL) && (fnode != NULL)
			    && (ftype != NULL)) {
				if (strcmp(filename, name) == 0) {
					*ftype = type;
					*fnode = fdiro;
					return 1;
				}
			} else {
				if (fdiro->inode_read == 0) {
					status = ext4fs_read_inode(diro->data,
								 le32_to_cpu(
								 dirent.inode),
								 &fdiro->inode);
					if (status == 0) {
						free(fdiro);
						return 0;
					}
					fdiro->inode_read = 1;
				}
				switch (type) {
				case FILETYPE_DIRECTORY:
					printf("<DIR> ");
					break;
				case FILETYPE_SYMLINK:
					printf("<SYM> ");
					break;
				case FILETYPE_REG:
					printf("      ");
					break;
				default:
					printf("< ? > ");
					break;
				}
				printf("%10u %s\n",
				       le32_to_cpu(fdiro->inode.size),
					filename);
			}
			free(fdiro);
		}
		fpos += le16_to_cpu(dirent.direntlen);
	}
	return 0;
}

static char *ext4fs_read_symlink(struct ext2fs_node *node)
{
	char *symlink;
	struct ext2fs_node *diro = node;
	int status;
	loff_t actread;

	if (!diro->inode_read) {
		status = ext4fs_read_inode(diro->data, diro->ino, &diro->inode);
		if (status == 0)
			return NULL;
	}
	symlink = zalloc(le32_to_cpu(diro->inode.size) + 1);
	if (!symlink)
		return NULL;

	if (le32_to_cpu(diro->inode.size) < sizeof(diro->inode.b.symlink)) {
		strncpy(symlink, diro->inode.b.symlink,
			 le32_to_cpu(diro->inode.size));
	} else {
		status = ext4fs_read_file(diro, 0,
					   le32_to_cpu(diro->inode.size),
					   symlink, &actread);
		if ((status < 0) || (actread == 0)) {
			free(symlink);
			return NULL;
		}
	}
	symlink[le32_to_cpu(diro->inode.size)] = '\0';
	return symlink;
}

int ext4fs_find_file1(const char *currpath, struct ext2fs_node *currroot,
		      struct ext2fs_node **currfound, int *foundtype)
{
	char fpath[strlen(currpath) + 1];
	char *name = fpath;
	char *next;
	int status;
	int type = FILETYPE_DIRECTORY;
	struct ext2fs_node *currnode = currroot;
	struct ext2fs_node *oldnode = currroot;

	strncpy(fpath, currpath, strlen(currpath) + 1);

	/* Remove all leading slashes. */
	while (*name == '/')
		name++;

	if (!*name) {
		*currfound = currnode;
		return 1;
	}

	for (;;) {
		int found;

		/* Extract the actual part from the pathname. */
		next = strchr(name, '/');
		if (next) {
			/* Remove all leading slashes. */
			while (*next == '/')
				*(next++) = '\0';
		}

		if (type != FILETYPE_DIRECTORY) {
			ext4fs_free_node(currnode, currroot);
			return 0;
		}

		oldnode = currnode;

		/* Iterate over the directory. */
		found = ext4fs_iterate_dir(currnode, name, &currnode, &type);
		if (found == 0)
			return 0;

		if (found == -1)
			break;

		/* Read in the symlink and follow it. */
		if (type == FILETYPE_SYMLINK) {
			char *symlink;

			/* Test if the symlink does not loop. */
			if (++symlinknest == 8) {
				ext4fs_free_node(currnode, currroot);
				ext4fs_free_node(oldnode, currroot);
				return 0;
			}

			symlink = ext4fs_read_symlink(currnode);
			ext4fs_free_node(currnode, currroot);

			if (!symlink) {
				ext4fs_free_node(oldnode, currroot);
				return 0;
			}

			debug("Got symlink >%s<\n", symlink);

			if (symlink[0] == '/') {
				ext4fs_free_node(oldnode, currroot);
				oldnode = &ext4fs_root->diropen;
			}

			/* Lookup the node the symlink points to. */
			status = ext4fs_find_file1(symlink, oldnode,
						    &currnode, &type);

			free(symlink);

			if (status == 0) {
				ext4fs_free_node(oldnode, currroot);
				return 0;
			}
		}

		ext4fs_free_node(oldnode, currroot);

		/* Found the node! */
		if (!next || *next == '\0') {
			*currfound = currnode;
			*foundtype = type;
			return 1;
		}
		name = next;
	}
	return -1;
}

int ext4fs_find_file(const char *path, struct ext2fs_node *rootnode,
	struct ext2fs_node **foundnode, int expecttype)
{
	int status;
	int foundtype = FILETYPE_DIRECTORY;

	symlinknest = 0;
	if (!path)
		return 0;

	status = ext4fs_find_file1(path, rootnode, foundnode, &foundtype);
	if (status == 0)
		return 0;

	/* Check if the node that was found was of the expected type. */
	if ((expecttype == FILETYPE_REG) && (foundtype != expecttype))
		return 0;
	else if ((expecttype == FILETYPE_DIRECTORY)
		   && (foundtype != expecttype))
		return 0;

	return 1;
}

int ext4fs_open(const char *filename, loff_t *len)
{
	struct ext2fs_node *fdiro = NULL;
	int status;

	if (ext4fs_root == NULL)
		return -1;

	ext4fs_file = NULL;
	status = ext4fs_find_file(filename, &ext4fs_root->diropen, &fdiro,
				  FILETYPE_REG);
	if (status == 0)
		goto fail;

	if (!fdiro->inode_read) {
		status = ext4fs_read_inode(fdiro->data, fdiro->ino,
				&fdiro->inode);
		if (status == 0)
			goto fail;
	}
	*len = le32_to_cpu(fdiro->inode.size);
	ext4fs_file = fdiro;

	return 0;
fail:
	ext4fs_free_node(fdiro, &ext4fs_root->diropen);

	return -1;
}

int ext4fs_mount(void)
{
	struct ext2_data *data;
	int status;
	struct ext_filesystem *fs = get_fs();
	data = zalloc(SUPERBLOCK_SIZE);
	if (!data)
		return 0;

	/* Read the superblock. */
	status = ext4_read_superblock((char *)&data->sblock);

	if (status == 0)
		goto fail;

	/* Make sure this is an ext2 filesystem. */
	if (le16_to_cpu(data->sblock.magic) != EXT2_MAGIC)
		goto fail_noerr;


	if (le32_to_cpu(data->sblock.revision_level) == 0) {
		fs->inodesz = 128;
		fs->gdsize = 32;
	} else {
		debug("EXT4 features COMPAT: %08x INCOMPAT: %08x RO_COMPAT: %08x\n",
		      __le32_to_cpu(data->sblock.feature_compatibility),
		      __le32_to_cpu(data->sblock.feature_incompat),
		      __le32_to_cpu(data->sblock.feature_ro_compat));

		fs->inodesz = le16_to_cpu(data->sblock.inode_size);
		fs->gdsize = le32_to_cpu(data->sblock.feature_incompat) &
			EXT4_FEATURE_INCOMPAT_64BIT ?
			le16_to_cpu(data->sblock.descriptor_size) : 32;
	}

	debug("EXT2 rev %d, inode_size %d, descriptor size %d\n",
	      le32_to_cpu(data->sblock.revision_level),
	      fs->inodesz, fs->gdsize);

	data->diropen.data = data;
	data->diropen.ino = 2;
	data->diropen.inode_read = 1;
	data->inode = &data->diropen.inode;

	status = ext4fs_read_inode(data, 2, data->inode);
	if (status == 0)
		goto fail;

	ext4fs_root = data;

	return 1;
fail:
	log_debug("Failed to mount ext2 filesystem...\n");
fail_noerr:
	free(data);
	ext4fs_root = NULL;

	return 0;
}
