/**
 * dir.c
 *
 * Many parts of codes are copied from Linux kernel/fs/f2fs.
 *
 * Copyright (C) 2015 Huawei Ltd.
 * Witten by:
 *   Hou Pengyang <houpengyang@huawei.com>
 *   Liu Shuoran <liushuoran@huawei.com>
 *   Jaegeuk Kim <jaegeuk@kernel.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include "fsck.h"
#include "node.h"

static int room_for_filename(const u8 *bitmap, int slots, int max_slots)
{
	int bit_start = 0;
	int zero_start, zero_end;
next:
	zero_start = find_next_zero_bit_le(bitmap, max_slots, bit_start);
	if (zero_start >= max_slots)
		return max_slots;

	zero_end = find_next_bit_le(bitmap, max_slots, zero_start + 1);

	if (zero_end - zero_start >= slots)
		return zero_start;
	bit_start = zero_end;
	goto next;

}

void make_dentry_ptr(struct f2fs_dentry_ptr *d, struct f2fs_node *node_blk,
							void *src, int type)
{
	if (type == 1) {
		struct f2fs_dentry_block *t = (struct f2fs_dentry_block *)src;
		d->max = NR_DENTRY_IN_BLOCK;
		d->nr_bitmap = SIZE_OF_DENTRY_BITMAP;
		d->bitmap = t->dentry_bitmap;
		d->dentry = t->dentry;
		d->filename = t->filename;
	} else {
		int entry_cnt = NR_INLINE_DENTRY(node_blk);
		int bitmap_size = INLINE_DENTRY_BITMAP_SIZE(node_blk);
		int reserved_size = INLINE_RESERVED_SIZE(node_blk);

		d->max = entry_cnt;
		d->nr_bitmap = bitmap_size;
		d->bitmap = (u8 *)src;
		d->dentry = (struct f2fs_dir_entry *)
				((char *)src + bitmap_size + reserved_size);
		d->filename = (__u8 (*)[F2FS_SLOT_LEN])((char *)src +
				bitmap_size + reserved_size +
				SIZE_OF_DIR_ENTRY * entry_cnt);
	}
}

static struct f2fs_dir_entry *find_target_dentry(const u8 *name,
		unsigned int len, f2fs_hash_t namehash, int *max_slots,
		struct f2fs_dentry_ptr *d)
{
	struct f2fs_dir_entry *de;
	unsigned long bit_pos = 0;
	int max_len = 0;

	if (max_slots)
		*max_slots = 0;
	while (bit_pos < (unsigned long)d->max) {
		if (!test_bit_le(bit_pos, d->bitmap)) {
			bit_pos++;
			max_len++;
			continue;
		}

		de = &d->dentry[bit_pos];
		if (le16_to_cpu(de->name_len) == len &&
			de->hash_code == namehash &&
			!memcmp(d->filename[bit_pos], name, len)) {
			goto found;
		}

		if (max_slots && max_len > *max_slots)
			*max_slots = max_len;
		max_len = 0;
		bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
	}
	de = NULL;
found:
	if (max_slots && max_len > *max_slots)
		*max_slots = max_len;
	return de;
}

static struct f2fs_dir_entry *find_in_block(void *block,
		const u8 *name, int len, f2fs_hash_t namehash,
		int *max_slots)
{
	struct f2fs_dentry_ptr d;

	make_dentry_ptr(&d, NULL, block, 1);
	return find_target_dentry(name, len, namehash, max_slots, &d);
}

static int find_in_level(struct f2fs_sb_info *sbi, struct f2fs_node *dir,
		unsigned int level, struct dentry *de)
{
	unsigned int nbucket, nblock;
	unsigned int bidx, end_block;
	struct f2fs_dir_entry *dentry = NULL;
	struct dnode_of_data dn;
	void *dentry_blk;
	int max_slots = 214;
	nid_t ino = le32_to_cpu(dir->footer.ino);
	f2fs_hash_t namehash;
	unsigned int dir_level = dir->i.i_dir_level;
	int ret = 0;

	namehash = f2fs_dentry_hash(get_encoding(sbi), IS_CASEFOLDED(&dir->i),
					de->name, de->len);

	nbucket = dir_buckets(level, dir_level);
	nblock = bucket_blocks(level);

	bidx = dir_block_index(level, dir_level, le32_to_cpu(namehash) % nbucket);
	end_block = bidx + nblock;

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

	memset(&dn, 0, sizeof(dn));
	for (; bidx < end_block; bidx++) {

		/* Firstly, we should know direct node of target data blk */
		if (dn.node_blk && dn.node_blk != dn.inode_blk)
			free(dn.node_blk);

		set_new_dnode(&dn, dir, NULL, ino);
		get_dnode_of_data(sbi, &dn, bidx, LOOKUP_NODE);
		if (dn.data_blkaddr == NULL_ADDR)
			continue;

		ret = dev_read_block(dentry_blk, dn.data_blkaddr);
		ASSERT(ret >= 0);

		dentry = find_in_block(dentry_blk, de->name, de->len,
						namehash, &max_slots);
		if (dentry) {
			ret = 1;
			de->ino = le32_to_cpu(dentry->ino);
			break;
		}
	}

	if (dn.node_blk && dn.node_blk != dn.inode_blk)
		free(dn.node_blk);
	free(dentry_blk);

	return ret;
}

static int f2fs_find_entry(struct f2fs_sb_info *sbi,
				struct f2fs_node *dir, struct dentry *de)
{
	unsigned int max_depth;
	unsigned int level;

	max_depth = le32_to_cpu(dir->i.i_current_depth);
	for (level = 0; level < max_depth; level ++) {
		if (find_in_level(sbi, dir, level, de))
			return 1;
	}
	return 0;
}

/* return ino if file exists, otherwise return 0 */
nid_t f2fs_lookup(struct f2fs_sb_info *sbi, struct f2fs_node *dir,
				u8 *name, int len)
{
	int err;
	struct dentry de = {
		.name = name,
		.len = len,
	};

	err = f2fs_find_entry(sbi, dir, &de);
	if (err == 1)
		return de.ino;
	else
		return 0;
}

static void f2fs_update_dentry(nid_t ino, int file_type,
		struct f2fs_dentry_ptr *d,
		const unsigned char *name, int len, f2fs_hash_t name_hash,
		unsigned int bit_pos)
{
	struct f2fs_dir_entry *de;
	int slots = GET_DENTRY_SLOTS(len);
	int i;

	de = &d->dentry[bit_pos];
	de->name_len = cpu_to_le16(len);
	de->hash_code = name_hash;
	memcpy(d->filename[bit_pos], name, len);
	d->filename[bit_pos][len] = 0;
	de->ino = cpu_to_le32(ino);
	de->file_type = file_type;
	for (i = 0; i < slots; i++)
		test_and_set_bit_le(bit_pos + i, d->bitmap);
}

/*
 * f2fs_add_link - Add a new file(dir) to parent dir.
 */
int f2fs_add_link(struct f2fs_sb_info *sbi, struct f2fs_node *parent,
			const unsigned char *name, int name_len, nid_t ino,
			int file_type, block_t p_blkaddr, int inc_link)
{
	int level = 0, current_depth, bit_pos;
	int nbucket, nblock, bidx, block;
	int slots = GET_DENTRY_SLOTS(name_len);
	f2fs_hash_t dentry_hash = f2fs_dentry_hash(get_encoding(sbi),
						IS_CASEFOLDED(&parent->i),
						name, name_len);
	struct f2fs_dentry_block *dentry_blk;
	struct f2fs_dentry_ptr d;
	struct dnode_of_data dn;
	nid_t pino = le32_to_cpu(parent->footer.ino);
	unsigned int dir_level = parent->i.i_dir_level;
	int ret;

	if (parent == NULL)
		return -EINVAL;

	if (!pino) {
		ERR_MSG("Wrong parent ino:%d \n", pino);
		return -EINVAL;
	}

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

	current_depth = le32_to_cpu(parent->i.i_current_depth);
start:
	if (current_depth == MAX_DIR_HASH_DEPTH) {
		free(dentry_blk);
		ERR_MSG("\tError: MAX_DIR_HASH\n");
		return -ENOSPC;
	}

	/* Need a new dentry block */
	if (level == current_depth)
		++current_depth;

	nbucket = dir_buckets(level, dir_level);
	nblock = bucket_blocks(level);
	bidx = dir_block_index(level, dir_level, le32_to_cpu(dentry_hash) % nbucket);

	memset(&dn, 0, sizeof(dn));
	for (block = bidx; block <= (bidx + nblock - 1); block++) {

		/* Firstly, we should know the direct node of target data blk */
		if (dn.node_blk && dn.node_blk != dn.inode_blk)
			free(dn.node_blk);

		set_new_dnode(&dn, parent, NULL, pino);
		get_dnode_of_data(sbi, &dn, block, ALLOC_NODE);

		if (dn.data_blkaddr == NULL_ADDR) {
			new_data_block(sbi, dentry_blk, &dn, CURSEG_HOT_DATA);
		} else {
			ret = dev_read_block(dentry_blk, dn.data_blkaddr);
			ASSERT(ret >= 0);
		}
		bit_pos = room_for_filename(dentry_blk->dentry_bitmap,
				slots, NR_DENTRY_IN_BLOCK);

		if (bit_pos < NR_DENTRY_IN_BLOCK)
			goto add_dentry;
	}
	level ++;
	goto start;

add_dentry:
	make_dentry_ptr(&d, NULL, (void *)dentry_blk, 1);
	f2fs_update_dentry(ino, file_type, &d, name, name_len, dentry_hash, bit_pos);

	ret = dev_write_block(dentry_blk, dn.data_blkaddr);
	ASSERT(ret >= 0);

	/*
	 * Parent inode needs updating, because its inode info may be changed.
	 * such as i_current_depth and i_blocks.
	 */
	if (parent->i.i_current_depth != cpu_to_le32(current_depth)) {
		parent->i.i_current_depth = cpu_to_le32(current_depth);
		dn.idirty = 1;
	}

	/* Update parent's i_links info*/
	if (inc_link && (file_type == F2FS_FT_DIR)){
		u32 links = le32_to_cpu(parent->i.i_links);
		parent->i.i_links = cpu_to_le32(links + 1);
		dn.idirty = 1;
	}

	if ((__u64)((block + 1) * F2FS_BLKSIZE) >
					le64_to_cpu(parent->i.i_size)) {
		parent->i.i_size = cpu_to_le64((block + 1) * F2FS_BLKSIZE);
		dn.idirty = 1;
	}

	if (dn.ndirty) {
		ret = dev_write_block(dn.node_blk, dn.node_blkaddr);
		ASSERT(ret >= 0);
	}

	if (dn.idirty) {
		ASSERT(parent == dn.inode_blk);
		ret = write_inode(dn.inode_blk, p_blkaddr);
		ASSERT(ret >= 0);
	}

	if (dn.node_blk != dn.inode_blk)
		free(dn.node_blk);
	free(dentry_blk);
	return 0;
}

static void make_empty_dir(struct f2fs_sb_info *sbi, struct f2fs_node *inode)
{
	struct f2fs_dentry_block *dent_blk;
	nid_t ino = le32_to_cpu(inode->footer.ino);
	nid_t pino = le32_to_cpu(inode->i.i_pino);
	struct f2fs_summary sum;
	struct node_info ni;
	block_t blkaddr = NULL_ADDR;
	int ret;

	get_node_info(sbi, ino, &ni);

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

	dent_blk->dentry[0].hash_code = 0;
	dent_blk->dentry[0].ino = cpu_to_le32(ino);
	dent_blk->dentry[0].name_len = cpu_to_le16(1);
	dent_blk->dentry[0].file_type = F2FS_FT_DIR;
	memcpy(dent_blk->filename[0], ".", 1);

	dent_blk->dentry[1].hash_code = 0;
	dent_blk->dentry[1].ino = cpu_to_le32(pino);
	dent_blk->dentry[1].name_len = cpu_to_le16(2);
	dent_blk->dentry[1].file_type = F2FS_FT_DIR;
	memcpy(dent_blk->filename[1], "..", 2);

	test_and_set_bit_le(0, dent_blk->dentry_bitmap);
	test_and_set_bit_le(1, dent_blk->dentry_bitmap);

	set_summary(&sum, ino, 0, ni.version);
	ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_HOT_DATA, 0);
	ASSERT(!ret);

	ret = dev_write_block(dent_blk, blkaddr);
	ASSERT(ret >= 0);

	inode->i.i_addr[get_extra_isize(inode)] = cpu_to_le32(blkaddr);
	free(dent_blk);
}

static void page_symlink(struct f2fs_sb_info *sbi, struct f2fs_node *inode,
					const char *symname, int symlen)
{
	nid_t ino = le32_to_cpu(inode->footer.ino);
	struct f2fs_summary sum;
	struct node_info ni;
	char *data_blk;
	block_t blkaddr = NULL_ADDR;
	int ret;

	get_node_info(sbi, ino, &ni);

	/* store into inline_data */
	if ((unsigned long)(symlen + 1) <= MAX_INLINE_DATA(inode)) {
		inode->i.i_inline |= F2FS_INLINE_DATA;
		inode->i.i_inline |= F2FS_DATA_EXIST;
		memcpy(inline_data_addr(inode), symname, symlen);
		return;
	}

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

	memcpy(data_blk, symname, symlen);

	set_summary(&sum, ino, 0, ni.version);
	ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_WARM_DATA, 1);
	ASSERT(!ret);

	ret = dev_write_block(data_blk, blkaddr);
	ASSERT(ret >= 0);

	inode->i.i_addr[get_extra_isize(inode)] = cpu_to_le32(blkaddr);
	free(data_blk);
}

static inline int is_extension_exist(const char *s,
					const char *sub)
{
	unsigned int slen = strlen(s);
	unsigned int  sublen = strlen(sub);
	int i;

	/*
	 * filename format of multimedia file should be defined as:
	 * "filename + '.' + extension + (optional: '.' + temp extension)".
	 */
	if (slen < sublen + 2)
		return 0;

	for (i = 1; i < slen - sublen; i++) {
		if (s[i] != '.')
			continue;
		if (!strncasecmp(s + i + 1, sub, sublen))
			return 1;
	}

	return 0;
}

static void set_file_temperature(struct f2fs_sb_info *sbi,
				struct f2fs_node *node_blk,
				const unsigned char *name)
{
	__u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
	int i, cold_count, hot_count;

	cold_count = le32_to_cpu(sbi->raw_super->extension_count);
	hot_count = sbi->raw_super->hot_ext_count;

	for (i = 0; i < cold_count + hot_count; i++) {
		if (is_extension_exist((const char *)name,
					(const char *)extlist[i]))
			break;
	}

	if (i == cold_count + hot_count)
		return;

	if (i < cold_count)
		node_blk->i.i_advise |= FADVISE_COLD_BIT;
	else
		node_blk->i.i_advise |= FADVISE_HOT_BIT;
}

static void init_inode_block(struct f2fs_sb_info *sbi,
		struct f2fs_node *node_blk, struct dentry *de)
{
	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
	mode_t mode = de->mode;
	int links = 1;
	unsigned int size;
	int blocks = 1;

	if (de->file_type == F2FS_FT_DIR) {
		mode |= S_IFDIR;
		size = 4096;
		links++;
		blocks++;
	} else if (de->file_type == F2FS_FT_REG_FILE) {
		mode |= S_IFREG;
		size = 0;
	} else if (de->file_type == F2FS_FT_SYMLINK) {
		ASSERT(de->link);
		mode |= S_IFLNK;
		size = strlen(de->link);
		if (size + 1 > MAX_INLINE_DATA(node_blk))
			blocks++;
	} else {
		ASSERT(0);
	}

	node_blk->i.i_mode = cpu_to_le16(mode);
	node_blk->i.i_advise = 0;
	node_blk->i.i_uid = cpu_to_le32(de->uid);
	node_blk->i.i_gid = cpu_to_le32(de->gid);
	node_blk->i.i_links = cpu_to_le32(links);
	node_blk->i.i_size = cpu_to_le32(size);
	node_blk->i.i_blocks = cpu_to_le32(blocks);
	node_blk->i.i_atime = cpu_to_le64(de->mtime);
	node_blk->i.i_ctime = cpu_to_le64(de->mtime);
	node_blk->i.i_mtime = cpu_to_le64(de->mtime);
	node_blk->i.i_atime_nsec = 0;
	node_blk->i.i_ctime_nsec = 0;
	node_blk->i.i_mtime_nsec = 0;
	node_blk->i.i_generation = 0;
	if (de->file_type == F2FS_FT_DIR)
		node_blk->i.i_current_depth = cpu_to_le32(1);
	else
		node_blk->i.i_current_depth = cpu_to_le32(0);
	node_blk->i.i_xattr_nid = 0;
	node_blk->i.i_flags = 0;
	node_blk->i.i_inline = F2FS_INLINE_XATTR;
	node_blk->i.i_pino = cpu_to_le32(de->pino);
	node_blk->i.i_namelen = cpu_to_le32(de->len);
	memcpy(node_blk->i.i_name, de->name, de->len);
	node_blk->i.i_name[de->len] = 0;

	if (c.feature & cpu_to_le32(F2FS_FEATURE_EXTRA_ATTR)) {
		node_blk->i.i_inline |= F2FS_EXTRA_ATTR;
		node_blk->i.i_extra_isize = cpu_to_le16(calc_extra_isize());
	}

	set_file_temperature(sbi, node_blk, de->name);

	node_blk->footer.ino = cpu_to_le32(de->ino);
	node_blk->footer.nid = cpu_to_le32(de->ino);
	node_blk->footer.flag = 0;
	node_blk->footer.cp_ver = ckpt->checkpoint_ver;

	if (S_ISDIR(mode)) {
		make_empty_dir(sbi, node_blk);
	} else if (S_ISLNK(mode)) {
		page_symlink(sbi, node_blk, de->link, size);

		free(de->link);
		de->link = NULL;
	}

	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
		node_blk->i.i_inode_checksum =
			cpu_to_le32(f2fs_inode_chksum(node_blk));
}

int convert_inline_dentry(struct f2fs_sb_info *sbi, struct f2fs_node *node,
							block_t p_blkaddr)
{
	struct f2fs_inode *inode = &(node->i);
	unsigned int dir_level = node->i.i_dir_level;
	nid_t ino = le32_to_cpu(node->footer.ino);
	char inline_data[MAX_INLINE_DATA(node)];
	struct dnode_of_data dn;
	struct f2fs_dentry_ptr d;
	unsigned long bit_pos = 0;
	int ret = 0;

	if (!(inode->i_inline & F2FS_INLINE_DENTRY))
		return 0;

	memcpy(inline_data, inline_data_addr(node), MAX_INLINE_DATA(node));
	memset(inline_data_addr(node), 0, MAX_INLINE_DATA(node));
	inode->i_inline &= ~F2FS_INLINE_DENTRY;

	ret = dev_write_block(node, p_blkaddr);
	ASSERT(ret >= 0);

	memset(&dn, 0, sizeof(dn));
	if (!dir_level) {
		struct f2fs_dentry_block *dentry_blk;
		struct f2fs_dentry_ptr src, dst;

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

		set_new_dnode(&dn, node, NULL, ino);
		get_dnode_of_data(sbi, &dn, 0, ALLOC_NODE);
		if (dn.data_blkaddr == NULL_ADDR)
			new_data_block(sbi, dentry_blk, &dn, CURSEG_HOT_DATA);

		make_dentry_ptr(&src, node, (void *)inline_data, 2);
		make_dentry_ptr(&dst, NULL, (void *)dentry_blk, 1);

		 /* copy data from inline dentry block to new dentry block */
		memcpy(dst.bitmap, src.bitmap, src.nr_bitmap);
		memset(dst.bitmap + src.nr_bitmap, 0,
					dst.nr_bitmap - src.nr_bitmap);

		memcpy(dst.dentry, src.dentry, SIZE_OF_DIR_ENTRY * src.max);
		memcpy(dst.filename, src.filename, src.max * F2FS_SLOT_LEN);

		ret = dev_write_block(dentry_blk, dn.data_blkaddr);
		ASSERT(ret >= 0);

		MSG(1, "%s: copy inline entry to block\n", __func__);

		free(dentry_blk);
		return ret;
	}

	make_empty_dir(sbi, node);
	make_dentry_ptr(&d, node, (void *)inline_data, 2);

	while (bit_pos < (unsigned long)d.max) {
		struct f2fs_dir_entry *de;
		const unsigned char *filename;
		int namelen;

		if (!test_bit_le(bit_pos, d.bitmap)) {
			bit_pos++;
			continue;
		}

		de = &d.dentry[bit_pos];
		if (!de->name_len) {
			bit_pos++;
			continue;
		}

		filename = d.filename[bit_pos];
		namelen = le32_to_cpu(de->name_len);

		if (is_dot_dotdot(filename, namelen)) {
			bit_pos += GET_DENTRY_SLOTS(namelen);
			continue;
		}

		ret = f2fs_add_link(sbi, node, filename, namelen,
				le32_to_cpu(de->ino),
				de->file_type, p_blkaddr, 0);
		if (ret)
			MSG(0, "Convert file \"%s\" ERR=%d\n", filename, ret);
		else
			MSG(1, "%s: add inline entry to block\n", __func__);

		bit_pos += GET_DENTRY_SLOTS(namelen);
	}

	return 0;
}

int f2fs_create(struct f2fs_sb_info *sbi, struct dentry *de)
{
	struct f2fs_node *parent, *child;
	struct node_info ni;
	struct f2fs_summary sum;
	block_t blkaddr = NULL_ADDR;
	int ret;

	/* Find if there is a */
	get_node_info(sbi, de->pino, &ni);
	if (ni.blk_addr == NULL_ADDR) {
		MSG(0, "No parent directory pino=%x\n", de->pino);
		return -1;
	}

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

	ret = dev_read_block(parent, ni.blk_addr);
	ASSERT(ret >= 0);

	/* Must convert inline dentry before the following opertions */
	ret = convert_inline_dentry(sbi, parent, ni.blk_addr);
	if (ret) {
		MSG(0, "Convert inline dentry for pino=%x failed.\n", de->pino);
		return -1;
	}

	ret = f2fs_find_entry(sbi, parent, de);
	if (ret) {
		MSG(0, "Skip the existing \"%s\" pino=%x ERR=%d\n",
					de->name, de->pino, ret);
		if (de->file_type == F2FS_FT_REG_FILE)
			de->ino = 0;
		goto free_parent_dir;
	}

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

	f2fs_alloc_nid(sbi, &de->ino);

	init_inode_block(sbi, child, de);

	ret = f2fs_add_link(sbi, parent, child->i.i_name,
				le32_to_cpu(child->i.i_namelen),
				le32_to_cpu(child->footer.ino),
				map_de_type(le16_to_cpu(child->i.i_mode)),
				ni.blk_addr, 1);
	if (ret) {
		MSG(0, "Skip the existing \"%s\" pino=%x ERR=%d\n",
					de->name, de->pino, ret);
		goto free_child_dir;
	}

	/* write child */
	set_summary(&sum, de->ino, 0, ni.version);
	ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_HOT_NODE, 1);
	ASSERT(!ret);

	/* update nat info */
	update_nat_blkaddr(sbi, de->ino, de->ino, blkaddr);

	ret = dev_write_block(child, blkaddr);
	ASSERT(ret >= 0);

	update_free_segments(sbi);
	MSG(1, "Info: Create %s -> %s\n"
		"  -- ino=%x, type=%x, mode=%x, uid=%x, "
		"gid=%x, cap=%"PRIx64", size=%lu, pino=%x\n",
		de->full_path, de->path,
		de->ino, de->file_type, de->mode,
		de->uid, de->gid, de->capabilities, de->size, de->pino);
free_child_dir:
	free(child);
free_parent_dir:
	free(parent);
	return 0;
}

int f2fs_mkdir(struct f2fs_sb_info *sbi, struct dentry *de)
{
	return f2fs_create(sbi, de);
}

int f2fs_symlink(struct f2fs_sb_info *sbi, struct dentry *de)
{
	return f2fs_create(sbi, de);
}

int f2fs_find_path(struct f2fs_sb_info *sbi, char *path, nid_t *ino)
{
	struct f2fs_node *parent;
	struct node_info ni;
	struct dentry de;
	int err = 0;
	int ret;
	char *p;

	if (path[0] != '/')
		return -ENOENT;

	*ino = F2FS_ROOT_INO(sbi);
	parent = calloc(BLOCK_SZ, 1);
	ASSERT(parent);

	p = strtok(path, "/");
	while (p) {
		de.name = (const u8 *)p;
		de.len = strlen(p);

		get_node_info(sbi, *ino, &ni);
		if (ni.blk_addr == NULL_ADDR) {
			err = -ENOENT;
			goto err;
		}
		ret = dev_read_block(parent, ni.blk_addr);
		ASSERT(ret >= 0);

		ret = f2fs_find_entry(sbi, parent, &de);
		if (!ret) {
			err = -ENOENT;
			goto err;
		}

		*ino = de.ino;
		p = strtok(NULL, "/");
	}
err:
	free(parent);
	return err;
}
