// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
 */

#include <linux/slab.h>
#include <linux/bio.h>
#include <linux/buffer_head.h>

#include "exfat_raw.h"
#include "exfat_fs.h"

static int exfat_extract_uni_name(struct exfat_dentry *ep,
		unsigned short *uniname)
{
	int i, len = 0;

	for (i = 0; i < EXFAT_FILE_NAME_LEN; i++) {
		*uniname = le16_to_cpu(ep->dentry.name.unicode_0_14[i]);
		if (*uniname == 0x0)
			return len;
		uniname++;
		len++;
	}

	*uniname = 0x0;
	return len;

}

static void exfat_get_uniname_from_ext_entry(struct super_block *sb,
		struct exfat_chain *p_dir, int entry, unsigned short *uniname)
{
	int i;
	struct exfat_entry_set_cache *es;
	unsigned int uni_len = 0, len;

	es = exfat_get_dentry_set(sb, p_dir, entry, ES_ALL_ENTRIES);
	if (!es)
		return;

	/*
	 * First entry  : file entry
	 * Second entry : stream-extension entry
	 * Third entry  : first file-name entry
	 * So, the index of first file-name dentry should start from 2.
	 */
	for (i = 2; i < es->num_entries; i++) {
		struct exfat_dentry *ep = exfat_get_dentry_cached(es, i);

		/* end of name entry */
		if (exfat_get_entry_type(ep) != TYPE_EXTEND)
			break;

		len = exfat_extract_uni_name(ep, uniname);
		uni_len += len;
		if (len != EXFAT_FILE_NAME_LEN || uni_len >= MAX_NAME_LENGTH)
			break;
		uniname += EXFAT_FILE_NAME_LEN;
	}

	exfat_free_dentry_set(es, false);
}

/* read a directory entry from the opened directory */
static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_entry *dir_entry)
{
	int i, dentries_per_clu, dentries_per_clu_bits = 0, num_ext;
	unsigned int type, clu_offset, max_dentries;
	sector_t sector;
	struct exfat_chain dir, clu;
	struct exfat_uni_name uni_name;
	struct exfat_dentry *ep;
	struct super_block *sb = inode->i_sb;
	struct exfat_sb_info *sbi = EXFAT_SB(sb);
	struct exfat_inode_info *ei = EXFAT_I(inode);
	unsigned int dentry = EXFAT_B_TO_DEN(*cpos) & 0xFFFFFFFF;
	struct buffer_head *bh;

	/* check if the given file ID is opened */
	if (ei->type != TYPE_DIR)
		return -EPERM;

	if (ei->entry == -1)
		exfat_chain_set(&dir, sbi->root_dir, 0, ALLOC_FAT_CHAIN);
	else
		exfat_chain_set(&dir, ei->start_clu,
			EXFAT_B_TO_CLU(i_size_read(inode), sbi), ei->flags);

	dentries_per_clu = sbi->dentries_per_clu;
	dentries_per_clu_bits = ilog2(dentries_per_clu);
	max_dentries = (unsigned int)min_t(u64, MAX_EXFAT_DENTRIES,
					   (u64)sbi->num_clusters << dentries_per_clu_bits);

	clu_offset = dentry >> dentries_per_clu_bits;
	exfat_chain_dup(&clu, &dir);

	if (clu.flags == ALLOC_NO_FAT_CHAIN) {
		clu.dir += clu_offset;
		clu.size -= clu_offset;
	} else {
		/* hint_information */
		if (clu_offset > 0 && ei->hint_bmap.off != EXFAT_EOF_CLUSTER &&
		    ei->hint_bmap.off > 0 && clu_offset >= ei->hint_bmap.off) {
			clu_offset -= ei->hint_bmap.off;
			clu.dir = ei->hint_bmap.clu;
		}

		while (clu_offset > 0 && clu.dir != EXFAT_EOF_CLUSTER) {
			if (exfat_get_next_cluster(sb, &(clu.dir)))
				return -EIO;

			clu_offset--;
		}
	}

	while (clu.dir != EXFAT_EOF_CLUSTER && dentry < max_dentries) {
		i = dentry & (dentries_per_clu - 1);

		for ( ; i < dentries_per_clu; i++, dentry++) {
			ep = exfat_get_dentry(sb, &clu, i, &bh, &sector);
			if (!ep)
				return -EIO;

			type = exfat_get_entry_type(ep);
			if (type == TYPE_UNUSED) {
				brelse(bh);
				break;
			}

			if (type != TYPE_FILE && type != TYPE_DIR) {
				brelse(bh);
				continue;
			}

			num_ext = ep->dentry.file.num_ext;
			dir_entry->attr = le16_to_cpu(ep->dentry.file.attr);
			exfat_get_entry_time(sbi, &dir_entry->crtime,
					ep->dentry.file.create_tz,
					ep->dentry.file.create_time,
					ep->dentry.file.create_date,
					ep->dentry.file.create_time_cs);
			exfat_get_entry_time(sbi, &dir_entry->mtime,
					ep->dentry.file.modify_tz,
					ep->dentry.file.modify_time,
					ep->dentry.file.modify_date,
					ep->dentry.file.modify_time_cs);
			exfat_get_entry_time(sbi, &dir_entry->atime,
					ep->dentry.file.access_tz,
					ep->dentry.file.access_time,
					ep->dentry.file.access_date,
					0);

			*uni_name.name = 0x0;
			exfat_get_uniname_from_ext_entry(sb, &clu, i,
				uni_name.name);
			exfat_utf16_to_nls(sb, &uni_name,
				dir_entry->namebuf.lfn,
				dir_entry->namebuf.lfnbuf_len);
			brelse(bh);

			ep = exfat_get_dentry(sb, &clu, i + 1, &bh, NULL);
			if (!ep)
				return -EIO;
			dir_entry->size =
				le64_to_cpu(ep->dentry.stream.valid_size);
			dir_entry->entry = dentry;
			brelse(bh);

			ei->hint_bmap.off = dentry >> dentries_per_clu_bits;
			ei->hint_bmap.clu = clu.dir;

			*cpos = EXFAT_DEN_TO_B(dentry + 1 + num_ext);
			return 0;
		}

		if (clu.flags == ALLOC_NO_FAT_CHAIN) {
			if (--clu.size > 0)
				clu.dir++;
			else
				clu.dir = EXFAT_EOF_CLUSTER;
		} else {
			if (exfat_get_next_cluster(sb, &(clu.dir)))
				return -EIO;
		}
	}

	dir_entry->namebuf.lfn[0] = '\0';
	*cpos = EXFAT_DEN_TO_B(dentry);
	return 0;
}

static void exfat_init_namebuf(struct exfat_dentry_namebuf *nb)
{
	nb->lfn = NULL;
	nb->lfnbuf_len = 0;
}

static int exfat_alloc_namebuf(struct exfat_dentry_namebuf *nb)
{
	nb->lfn = __getname();
	if (!nb->lfn)
		return -ENOMEM;
	nb->lfnbuf_len = MAX_VFSNAME_BUF_SIZE;
	return 0;
}

static void exfat_free_namebuf(struct exfat_dentry_namebuf *nb)
{
	if (!nb->lfn)
		return;

	__putname(nb->lfn);
	exfat_init_namebuf(nb);
}

/*
 * Before calling dir_emit*(), sbi->s_lock should be released
 * because page fault can occur in dir_emit*().
 */
#define ITER_POS_FILLED_DOTS    (2)
static int exfat_iterate(struct file *filp, struct dir_context *ctx)
{
	struct inode *inode = filp->f_path.dentry->d_inode;
	struct super_block *sb = inode->i_sb;
	struct inode *tmp;
	struct exfat_dir_entry de;
	struct exfat_dentry_namebuf *nb = &(de.namebuf);
	struct exfat_inode_info *ei = EXFAT_I(inode);
	unsigned long inum;
	loff_t cpos, i_pos;
	int err = 0, fake_offset = 0;

	exfat_init_namebuf(nb);

	cpos = ctx->pos;
	if (!dir_emit_dots(filp, ctx))
		goto out;

	if (ctx->pos == ITER_POS_FILLED_DOTS) {
		cpos = 0;
		fake_offset = 1;
	}

	cpos = round_up(cpos, DENTRY_SIZE);

	/* name buffer should be allocated before use */
	err = exfat_alloc_namebuf(nb);
	if (err)
		goto out;
get_new:
	mutex_lock(&EXFAT_SB(sb)->s_lock);

	if (ei->flags == ALLOC_NO_FAT_CHAIN && cpos >= i_size_read(inode))
		goto end_of_dir;

	err = exfat_readdir(inode, &cpos, &de);
	if (err) {
		/*
		 * At least we tried to read a sector.
		 * Move cpos to next sector position (should be aligned).
		 */
		if (err == -EIO) {
			cpos += 1 << (sb->s_blocksize_bits);
			cpos &= ~(sb->s_blocksize - 1);
		}

		err = -EIO;
		goto end_of_dir;
	}

	if (!nb->lfn[0])
		goto end_of_dir;

	i_pos = ((loff_t)ei->start_clu << 32) |	(de.entry & 0xffffffff);
	tmp = exfat_iget(sb, i_pos);
	if (tmp) {
		inum = tmp->i_ino;
		iput(tmp);
	} else {
		inum = iunique(sb, EXFAT_ROOT_INO);
	}

	mutex_unlock(&EXFAT_SB(sb)->s_lock);
	if (!dir_emit(ctx, nb->lfn, strlen(nb->lfn), inum,
			(de.attr & ATTR_SUBDIR) ? DT_DIR : DT_REG))
		goto out;
	ctx->pos = cpos;
	goto get_new;

end_of_dir:
	if (!cpos && fake_offset)
		cpos = ITER_POS_FILLED_DOTS;
	ctx->pos = cpos;
	mutex_unlock(&EXFAT_SB(sb)->s_lock);
out:
	/*
	 * To improve performance, free namebuf after unlock sb_lock.
	 * If namebuf is not allocated, this function do nothing
	 */
	exfat_free_namebuf(nb);
	return err;
}

const struct file_operations exfat_dir_operations = {
	.llseek		= generic_file_llseek,
	.read		= generic_read_dir,
	.iterate	= exfat_iterate,
	.fsync		= exfat_file_fsync,
};

int exfat_alloc_new_dir(struct inode *inode, struct exfat_chain *clu)
{
	int ret;

	exfat_chain_set(clu, EXFAT_EOF_CLUSTER, 0, ALLOC_NO_FAT_CHAIN);

	ret = exfat_alloc_cluster(inode, 1, clu);
	if (ret)
		return ret;

	return exfat_zeroed_cluster(inode, clu->dir);
}

int exfat_calc_num_entries(struct exfat_uni_name *p_uniname)
{
	int len;

	len = p_uniname->name_len;
	if (len == 0)
		return -EINVAL;

	/* 1 file entry + 1 stream entry + name entries */
	return ((len - 1) / EXFAT_FILE_NAME_LEN + 3);
}

unsigned int exfat_get_entry_type(struct exfat_dentry *ep)
{
	if (ep->type == EXFAT_UNUSED)
		return TYPE_UNUSED;
	if (IS_EXFAT_DELETED(ep->type))
		return TYPE_DELETED;
	if (ep->type == EXFAT_INVAL)
		return TYPE_INVALID;
	if (IS_EXFAT_CRITICAL_PRI(ep->type)) {
		if (ep->type == EXFAT_BITMAP)
			return TYPE_BITMAP;
		if (ep->type == EXFAT_UPCASE)
			return TYPE_UPCASE;
		if (ep->type == EXFAT_VOLUME)
			return TYPE_VOLUME;
		if (ep->type == EXFAT_FILE) {
			if (le16_to_cpu(ep->dentry.file.attr) & ATTR_SUBDIR)
				return TYPE_DIR;
			return TYPE_FILE;
		}
		return TYPE_CRITICAL_PRI;
	}
	if (IS_EXFAT_BENIGN_PRI(ep->type)) {
		if (ep->type == EXFAT_GUID)
			return TYPE_GUID;
		if (ep->type == EXFAT_PADDING)
			return TYPE_PADDING;
		if (ep->type == EXFAT_ACLTAB)
			return TYPE_ACLTAB;
		return TYPE_BENIGN_PRI;
	}
	if (IS_EXFAT_CRITICAL_SEC(ep->type)) {
		if (ep->type == EXFAT_STREAM)
			return TYPE_STREAM;
		if (ep->type == EXFAT_NAME)
			return TYPE_EXTEND;
		if (ep->type == EXFAT_ACL)
			return TYPE_ACL;
		return TYPE_CRITICAL_SEC;
	}
	return TYPE_BENIGN_SEC;
}

static void exfat_set_entry_type(struct exfat_dentry *ep, unsigned int type)
{
	if (type == TYPE_UNUSED) {
		ep->type = EXFAT_UNUSED;
	} else if (type == TYPE_DELETED) {
		ep->type &= EXFAT_DELETE;
	} else if (type == TYPE_STREAM) {
		ep->type = EXFAT_STREAM;
	} else if (type == TYPE_EXTEND) {
		ep->type = EXFAT_NAME;
	} else if (type == TYPE_BITMAP) {
		ep->type = EXFAT_BITMAP;
	} else if (type == TYPE_UPCASE) {
		ep->type = EXFAT_UPCASE;
	} else if (type == TYPE_VOLUME) {
		ep->type = EXFAT_VOLUME;
	} else if (type == TYPE_DIR) {
		ep->type = EXFAT_FILE;
		ep->dentry.file.attr = cpu_to_le16(ATTR_SUBDIR);
	} else if (type == TYPE_FILE) {
		ep->type = EXFAT_FILE;
		ep->dentry.file.attr = cpu_to_le16(ATTR_ARCHIVE);
	}
}

static void exfat_init_stream_entry(struct exfat_dentry *ep,
		unsigned char flags, unsigned int start_clu,
		unsigned long long size)
{
	exfat_set_entry_type(ep, TYPE_STREAM);
	ep->dentry.stream.flags = flags;
	ep->dentry.stream.start_clu = cpu_to_le32(start_clu);
	ep->dentry.stream.valid_size = cpu_to_le64(size);
	ep->dentry.stream.size = cpu_to_le64(size);
}

static void exfat_init_name_entry(struct exfat_dentry *ep,
		unsigned short *uniname)
{
	int i;

	exfat_set_entry_type(ep, TYPE_EXTEND);
	ep->dentry.name.flags = 0x0;

	for (i = 0; i < EXFAT_FILE_NAME_LEN; i++) {
		if (*uniname != 0x0) {
			ep->dentry.name.unicode_0_14[i] = cpu_to_le16(*uniname);
			uniname++;
		} else {
			ep->dentry.name.unicode_0_14[i] = 0x0;
		}
	}
}

int exfat_init_dir_entry(struct inode *inode, struct exfat_chain *p_dir,
		int entry, unsigned int type, unsigned int start_clu,
		unsigned long long size)
{
	struct super_block *sb = inode->i_sb;
	struct exfat_sb_info *sbi = EXFAT_SB(sb);
	struct timespec64 ts = current_time(inode);
	sector_t sector;
	struct exfat_dentry *ep;
	struct buffer_head *bh;

	/*
	 * We cannot use exfat_get_dentry_set here because file ep is not
	 * initialized yet.
	 */
	ep = exfat_get_dentry(sb, p_dir, entry, &bh, &sector);
	if (!ep)
		return -EIO;

	exfat_set_entry_type(ep, type);
	exfat_set_entry_time(sbi, &ts,
			&ep->dentry.file.create_tz,
			&ep->dentry.file.create_time,
			&ep->dentry.file.create_date,
			&ep->dentry.file.create_time_cs);
	exfat_set_entry_time(sbi, &ts,
			&ep->dentry.file.modify_tz,
			&ep->dentry.file.modify_time,
			&ep->dentry.file.modify_date,
			&ep->dentry.file.modify_time_cs);
	exfat_set_entry_time(sbi, &ts,
			&ep->dentry.file.access_tz,
			&ep->dentry.file.access_time,
			&ep->dentry.file.access_date,
			NULL);

	exfat_update_bh(bh, IS_DIRSYNC(inode));
	brelse(bh);

	ep = exfat_get_dentry(sb, p_dir, entry + 1, &bh, &sector);
	if (!ep)
		return -EIO;

	exfat_init_stream_entry(ep,
		(type == TYPE_FILE) ? ALLOC_FAT_CHAIN : ALLOC_NO_FAT_CHAIN,
		start_clu, size);
	exfat_update_bh(bh, IS_DIRSYNC(inode));
	brelse(bh);

	return 0;
}

int exfat_update_dir_chksum(struct inode *inode, struct exfat_chain *p_dir,
		int entry)
{
	struct super_block *sb = inode->i_sb;
	int ret = 0;
	int i, num_entries;
	sector_t sector;
	u16 chksum;
	struct exfat_dentry *ep, *fep;
	struct buffer_head *fbh, *bh;

	fep = exfat_get_dentry(sb, p_dir, entry, &fbh, &sector);
	if (!fep)
		return -EIO;

	num_entries = fep->dentry.file.num_ext + 1;
	chksum = exfat_calc_chksum16(fep, DENTRY_SIZE, 0, CS_DIR_ENTRY);

	for (i = 1; i < num_entries; i++) {
		ep = exfat_get_dentry(sb, p_dir, entry + i, &bh, NULL);
		if (!ep) {
			ret = -EIO;
			goto release_fbh;
		}
		chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, chksum,
				CS_DEFAULT);
		brelse(bh);
	}

	fep->dentry.file.checksum = cpu_to_le16(chksum);
	exfat_update_bh(fbh, IS_DIRSYNC(inode));
release_fbh:
	brelse(fbh);
	return ret;
}

int exfat_init_ext_entry(struct inode *inode, struct exfat_chain *p_dir,
		int entry, int num_entries, struct exfat_uni_name *p_uniname)
{
	struct super_block *sb = inode->i_sb;
	int i;
	sector_t sector;
	unsigned short *uniname = p_uniname->name;
	struct exfat_dentry *ep;
	struct buffer_head *bh;
	int sync = IS_DIRSYNC(inode);

	ep = exfat_get_dentry(sb, p_dir, entry, &bh, &sector);
	if (!ep)
		return -EIO;

	ep->dentry.file.num_ext = (unsigned char)(num_entries - 1);
	exfat_update_bh(bh, sync);
	brelse(bh);

	ep = exfat_get_dentry(sb, p_dir, entry + 1, &bh, &sector);
	if (!ep)
		return -EIO;

	ep->dentry.stream.name_len = p_uniname->name_len;
	ep->dentry.stream.name_hash = cpu_to_le16(p_uniname->name_hash);
	exfat_update_bh(bh, sync);
	brelse(bh);

	for (i = EXFAT_FIRST_CLUSTER; i < num_entries; i++) {
		ep = exfat_get_dentry(sb, p_dir, entry + i, &bh, &sector);
		if (!ep)
			return -EIO;

		exfat_init_name_entry(ep, uniname);
		exfat_update_bh(bh, sync);
		brelse(bh);
		uniname += EXFAT_FILE_NAME_LEN;
	}

	exfat_update_dir_chksum(inode, p_dir, entry);
	return 0;
}

int exfat_remove_entries(struct inode *inode, struct exfat_chain *p_dir,
		int entry, int order, int num_entries)
{
	struct super_block *sb = inode->i_sb;
	int i;
	sector_t sector;
	struct exfat_dentry *ep;
	struct buffer_head *bh;

	for (i = order; i < num_entries; i++) {
		ep = exfat_get_dentry(sb, p_dir, entry + i, &bh, &sector);
		if (!ep)
			return -EIO;

		exfat_set_entry_type(ep, TYPE_DELETED);
		exfat_update_bh(bh, IS_DIRSYNC(inode));
		brelse(bh);
	}

	return 0;
}

void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es)
{
	int chksum_type = CS_DIR_ENTRY, i;
	unsigned short chksum = 0;
	struct exfat_dentry *ep;

	for (i = 0; i < es->num_entries; i++) {
		ep = exfat_get_dentry_cached(es, i);
		chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, chksum,
					     chksum_type);
		chksum_type = CS_DEFAULT;
	}
	ep = exfat_get_dentry_cached(es, 0);
	ep->dentry.file.checksum = cpu_to_le16(chksum);
	es->modified = true;
}

int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync)
{
	int i, err = 0;

	if (es->modified)
		err = exfat_update_bhs(es->bh, es->num_bh, sync);

	for (i = 0; i < es->num_bh; i++)
		if (err)
			bforget(es->bh[i]);
		else
			brelse(es->bh[i]);

	if (IS_DYNAMIC_ES(es))
		kfree(es->bh);

	kfree(es);
	return err;
}

static int exfat_walk_fat_chain(struct super_block *sb,
		struct exfat_chain *p_dir, unsigned int byte_offset,
		unsigned int *clu)
{
	struct exfat_sb_info *sbi = EXFAT_SB(sb);
	unsigned int clu_offset;
	unsigned int cur_clu;

	clu_offset = EXFAT_B_TO_CLU(byte_offset, sbi);
	cur_clu = p_dir->dir;

	if (p_dir->flags == ALLOC_NO_FAT_CHAIN) {
		cur_clu += clu_offset;
	} else {
		while (clu_offset > 0) {
			if (exfat_get_next_cluster(sb, &cur_clu))
				return -EIO;
			if (cur_clu == EXFAT_EOF_CLUSTER) {
				exfat_fs_error(sb,
					"invalid dentry access beyond EOF (clu : %u, eidx : %d)",
					p_dir->dir,
					EXFAT_B_TO_DEN(byte_offset));
				return -EIO;
			}
			clu_offset--;
		}
	}

	*clu = cur_clu;
	return 0;
}

int exfat_find_location(struct super_block *sb, struct exfat_chain *p_dir,
		int entry, sector_t *sector, int *offset)
{
	int ret;
	unsigned int off, clu = 0;
	struct exfat_sb_info *sbi = EXFAT_SB(sb);

	off = EXFAT_DEN_TO_B(entry);

	ret = exfat_walk_fat_chain(sb, p_dir, off, &clu);
	if (ret)
		return ret;

	/* byte offset in cluster */
	off = EXFAT_CLU_OFFSET(off, sbi);

	/* byte offset in sector    */
	*offset = EXFAT_BLK_OFFSET(off, sb);

	/* sector offset in cluster */
	*sector = EXFAT_B_TO_BLK(off, sb);
	*sector += exfat_cluster_to_sector(sbi, clu);
	return 0;
}

#define EXFAT_MAX_RA_SIZE     (128*1024)
static int exfat_dir_readahead(struct super_block *sb, sector_t sec)
{
	struct exfat_sb_info *sbi = EXFAT_SB(sb);
	struct buffer_head *bh;
	unsigned int max_ra_count = EXFAT_MAX_RA_SIZE >> sb->s_blocksize_bits;
	unsigned int page_ra_count = PAGE_SIZE >> sb->s_blocksize_bits;
	unsigned int adj_ra_count = max(sbi->sect_per_clus, page_ra_count);
	unsigned int ra_count = min(adj_ra_count, max_ra_count);

	/* Read-ahead is not required */
	if (sbi->sect_per_clus == 1)
		return 0;

	if (sec < sbi->data_start_sector) {
		exfat_err(sb, "requested sector is invalid(sect:%llu, root:%llu)",
			  (unsigned long long)sec, sbi->data_start_sector);
		return -EIO;
	}

	/* Not sector aligned with ra_count, resize ra_count to page size */
	if ((sec - sbi->data_start_sector) & (ra_count - 1))
		ra_count = page_ra_count;

	bh = sb_find_get_block(sb, sec);
	if (!bh || !buffer_uptodate(bh)) {
		unsigned int i;

		for (i = 0; i < ra_count; i++)
			sb_breadahead(sb, (sector_t)(sec + i));
	}
	brelse(bh);
	return 0;
}

struct exfat_dentry *exfat_get_dentry(struct super_block *sb,
		struct exfat_chain *p_dir, int entry, struct buffer_head **bh,
		sector_t *sector)
{
	unsigned int dentries_per_page = EXFAT_B_TO_DEN(PAGE_SIZE);
	int off;
	sector_t sec;

	if (p_dir->dir == DIR_DELETED) {
		exfat_err(sb, "abnormal access to deleted dentry");
		return NULL;
	}

	if (exfat_find_location(sb, p_dir, entry, &sec, &off))
		return NULL;

	if (p_dir->dir != EXFAT_FREE_CLUSTER &&
			!(entry & (dentries_per_page - 1)))
		exfat_dir_readahead(sb, sec);

	*bh = sb_bread(sb, sec);
	if (!*bh)
		return NULL;

	if (sector)
		*sector = sec;
	return (struct exfat_dentry *)((*bh)->b_data + off);
}

enum exfat_validate_dentry_mode {
	ES_MODE_STARTED,
	ES_MODE_GET_FILE_ENTRY,
	ES_MODE_GET_STRM_ENTRY,
	ES_MODE_GET_NAME_ENTRY,
	ES_MODE_GET_CRITICAL_SEC_ENTRY,
};

static bool exfat_validate_entry(unsigned int type,
		enum exfat_validate_dentry_mode *mode)
{
	if (type == TYPE_UNUSED || type == TYPE_DELETED)
		return false;

	switch (*mode) {
	case ES_MODE_STARTED:
		if  (type != TYPE_FILE && type != TYPE_DIR)
			return false;
		*mode = ES_MODE_GET_FILE_ENTRY;
		return true;
	case ES_MODE_GET_FILE_ENTRY:
		if (type != TYPE_STREAM)
			return false;
		*mode = ES_MODE_GET_STRM_ENTRY;
		return true;
	case ES_MODE_GET_STRM_ENTRY:
		if (type != TYPE_EXTEND)
			return false;
		*mode = ES_MODE_GET_NAME_ENTRY;
		return true;
	case ES_MODE_GET_NAME_ENTRY:
		if (type == TYPE_STREAM)
			return false;
		if (type != TYPE_EXTEND) {
			if (!(type & TYPE_CRITICAL_SEC))
				return false;
			*mode = ES_MODE_GET_CRITICAL_SEC_ENTRY;
		}
		return true;
	case ES_MODE_GET_CRITICAL_SEC_ENTRY:
		if (type == TYPE_EXTEND || type == TYPE_STREAM)
			return false;
		if ((type & TYPE_CRITICAL_SEC) != TYPE_CRITICAL_SEC)
			return false;
		return true;
	default:
		WARN_ON_ONCE(1);
		return false;
	}
}

struct exfat_dentry *exfat_get_dentry_cached(
	struct exfat_entry_set_cache *es, int num)
{
	int off = es->start_off + num * DENTRY_SIZE;
	struct buffer_head *bh = es->bh[EXFAT_B_TO_BLK(off, es->sb)];
	char *p = bh->b_data + EXFAT_BLK_OFFSET(off, es->sb);

	return (struct exfat_dentry *)p;
}

/*
 * Returns a set of dentries for a file or dir.
 *
 * Note It provides a direct pointer to bh->data via exfat_get_dentry_cached().
 * User should call exfat_get_dentry_set() after setting 'modified' to apply
 * changes made in this entry set to the real device.
 *
 * in:
 *   sb+p_dir+entry: indicates a file/dir
 *   type:  specifies how many dentries should be included.
 * return:
 *   pointer of entry set on success,
 *   NULL on failure.
 */
struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
		struct exfat_chain *p_dir, int entry, unsigned int type)
{
	int ret, i, num_bh;
	unsigned int off, byte_offset, clu = 0;
	sector_t sec;
	struct exfat_sb_info *sbi = EXFAT_SB(sb);
	struct exfat_entry_set_cache *es;
	struct exfat_dentry *ep;
	int num_entries;
	enum exfat_validate_dentry_mode mode = ES_MODE_STARTED;
	struct buffer_head *bh;

	if (p_dir->dir == DIR_DELETED) {
		exfat_err(sb, "access to deleted dentry");
		return NULL;
	}

	byte_offset = EXFAT_DEN_TO_B(entry);
	ret = exfat_walk_fat_chain(sb, p_dir, byte_offset, &clu);
	if (ret)
		return NULL;

	es = kzalloc(sizeof(*es), GFP_KERNEL);
	if (!es)
		return NULL;
	es->sb = sb;
	es->modified = false;

	/* byte offset in cluster */
	byte_offset = EXFAT_CLU_OFFSET(byte_offset, sbi);

	/* byte offset in sector */
	off = EXFAT_BLK_OFFSET(byte_offset, sb);
	es->start_off = off;
	es->bh = es->__bh;

	/* sector offset in cluster */
	sec = EXFAT_B_TO_BLK(byte_offset, sb);
	sec += exfat_cluster_to_sector(sbi, clu);

	bh = sb_bread(sb, sec);
	if (!bh)
		goto free_es;
	es->bh[es->num_bh++] = bh;

	ep = exfat_get_dentry_cached(es, 0);
	if (!exfat_validate_entry(exfat_get_entry_type(ep), &mode))
		goto free_es;

	num_entries = type == ES_ALL_ENTRIES ?
		ep->dentry.file.num_ext + 1 : type;
	es->num_entries = num_entries;

	num_bh = EXFAT_B_TO_BLK_ROUND_UP(off + num_entries * DENTRY_SIZE, sb);
	if (num_bh > ARRAY_SIZE(es->__bh)) {
		es->bh = kmalloc_array(num_bh, sizeof(*es->bh), GFP_KERNEL);
		if (!es->bh) {
			brelse(bh);
			kfree(es);
			return NULL;
		}
		es->bh[0] = bh;
	}

	for (i = 1; i < num_bh; i++) {
		/* get the next sector */
		if (exfat_is_last_sector_in_cluster(sbi, sec)) {
			if (p_dir->flags == ALLOC_NO_FAT_CHAIN)
				clu++;
			else if (exfat_get_next_cluster(sb, &clu))
				goto free_es;
			sec = exfat_cluster_to_sector(sbi, clu);
		} else {
			sec++;
		}

		bh = sb_bread(sb, sec);
		if (!bh)
			goto free_es;
		es->bh[es->num_bh++] = bh;
	}

	/* validiate cached dentries */
	for (i = 1; i < num_entries; i++) {
		ep = exfat_get_dentry_cached(es, i);
		if (!exfat_validate_entry(exfat_get_entry_type(ep), &mode))
			goto free_es;
	}
	return es;

free_es:
	exfat_free_dentry_set(es, false);
	return NULL;
}

enum {
	DIRENT_STEP_FILE,
	DIRENT_STEP_STRM,
	DIRENT_STEP_NAME,
	DIRENT_STEP_SECD,
};

/*
 * @ei:         inode info of parent directory
 * @p_dir:      directory structure of parent directory
 * @num_entries:entry size of p_uniname
 * @hint_opt:   If p_uniname is found, filled with optimized dir/entry
 *              for traversing cluster chain.
 * @return:
 *   >= 0:      file directory entry position where the name exists
 *   -ENOENT:   entry with the name does not exist
 *   -EIO:      I/O error
 */
int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
		struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname,
		int num_entries, unsigned int type, struct exfat_hint *hint_opt)
{
	int i, rewind = 0, dentry = 0, end_eidx = 0, num_ext = 0, len;
	int order, step, name_len = 0;
	int dentries_per_clu, num_empty = 0;
	unsigned int entry_type;
	unsigned short *uniname = NULL;
	struct exfat_chain clu;
	struct exfat_hint *hint_stat = &ei->hint_stat;
	struct exfat_hint_femp candi_empty;
	struct exfat_sb_info *sbi = EXFAT_SB(sb);

	dentries_per_clu = sbi->dentries_per_clu;

	exfat_chain_dup(&clu, p_dir);

	if (hint_stat->eidx) {
		clu.dir = hint_stat->clu;
		dentry = hint_stat->eidx;
		end_eidx = dentry;
	}

	candi_empty.eidx = EXFAT_HINT_NONE;
rewind:
	order = 0;
	step = DIRENT_STEP_FILE;
	while (clu.dir != EXFAT_EOF_CLUSTER) {
		i = dentry & (dentries_per_clu - 1);
		for (; i < dentries_per_clu; i++, dentry++) {
			struct exfat_dentry *ep;
			struct buffer_head *bh;

			if (rewind && dentry == end_eidx)
				goto not_found;

			ep = exfat_get_dentry(sb, &clu, i, &bh, NULL);
			if (!ep)
				return -EIO;

			entry_type = exfat_get_entry_type(ep);

			if (entry_type == TYPE_UNUSED ||
			    entry_type == TYPE_DELETED) {
				step = DIRENT_STEP_FILE;

				num_empty++;
				if (candi_empty.eidx == EXFAT_HINT_NONE &&
						num_empty == 1) {
					exfat_chain_set(&candi_empty.cur,
						clu.dir, clu.size, clu.flags);
				}

				if (candi_empty.eidx == EXFAT_HINT_NONE &&
						num_empty >= num_entries) {
					candi_empty.eidx =
						dentry - (num_empty - 1);
					WARN_ON(candi_empty.eidx < 0);
					candi_empty.count = num_empty;

					if (ei->hint_femp.eidx ==
							EXFAT_HINT_NONE ||
						candi_empty.eidx <=
							 ei->hint_femp.eidx)
						ei->hint_femp = candi_empty;
				}

				brelse(bh);
				if (entry_type == TYPE_UNUSED)
					goto not_found;
				continue;
			}

			num_empty = 0;
			candi_empty.eidx = EXFAT_HINT_NONE;

			if (entry_type == TYPE_FILE || entry_type == TYPE_DIR) {
				step = DIRENT_STEP_FILE;
				hint_opt->clu = clu.dir;
				hint_opt->eidx = i;
				if (type == TYPE_ALL || type == entry_type) {
					num_ext = ep->dentry.file.num_ext;
					step = DIRENT_STEP_STRM;
				}
				brelse(bh);
				continue;
			}

			if (entry_type == TYPE_STREAM) {
				u16 name_hash;

				if (step != DIRENT_STEP_STRM) {
					step = DIRENT_STEP_FILE;
					brelse(bh);
					continue;
				}
				step = DIRENT_STEP_FILE;
				name_hash = le16_to_cpu(
						ep->dentry.stream.name_hash);
				if (p_uniname->name_hash == name_hash &&
				    p_uniname->name_len ==
						ep->dentry.stream.name_len) {
					step = DIRENT_STEP_NAME;
					order = 1;
					name_len = 0;
				}
				brelse(bh);
				continue;
			}

			brelse(bh);
			if (entry_type == TYPE_EXTEND) {
				unsigned short entry_uniname[16], unichar;

				if (step != DIRENT_STEP_NAME ||
				    name_len >= MAX_NAME_LENGTH) {
					step = DIRENT_STEP_FILE;
					continue;
				}

				if (++order == 2)
					uniname = p_uniname->name;
				else
					uniname += EXFAT_FILE_NAME_LEN;

				len = exfat_extract_uni_name(ep, entry_uniname);
				name_len += len;

				unichar = *(uniname+len);
				*(uniname+len) = 0x0;

				if (exfat_uniname_ncmp(sb, uniname,
					entry_uniname, len)) {
					step = DIRENT_STEP_FILE;
				} else if (p_uniname->name_len == name_len) {
					if (order == num_ext)
						goto found;
					step = DIRENT_STEP_SECD;
				}

				*(uniname+len) = unichar;
				continue;
			}

			if (entry_type &
					(TYPE_CRITICAL_SEC | TYPE_BENIGN_SEC)) {
				if (step == DIRENT_STEP_SECD) {
					if (++order == num_ext)
						goto found;
					continue;
				}
			}
			step = DIRENT_STEP_FILE;
		}

		if (clu.flags == ALLOC_NO_FAT_CHAIN) {
			if (--clu.size > 0)
				clu.dir++;
			else
				clu.dir = EXFAT_EOF_CLUSTER;
		} else {
			if (exfat_get_next_cluster(sb, &clu.dir))
				return -EIO;
		}
	}

not_found:
	/*
	 * We started at not 0 index,so we should try to find target
	 * from 0 index to the index we started at.
	 */
	if (!rewind && end_eidx) {
		rewind = 1;
		dentry = 0;
		clu.dir = p_dir->dir;
		/* reset empty hint */
		num_empty = 0;
		candi_empty.eidx = EXFAT_HINT_NONE;
		goto rewind;
	}

	/* initialized hint_stat */
	hint_stat->clu = p_dir->dir;
	hint_stat->eidx = 0;
	return -ENOENT;

found:
	/* next dentry we'll find is out of this cluster */
	if (!((dentry + 1) & (dentries_per_clu - 1))) {
		int ret = 0;

		if (clu.flags == ALLOC_NO_FAT_CHAIN) {
			if (--clu.size > 0)
				clu.dir++;
			else
				clu.dir = EXFAT_EOF_CLUSTER;
		} else {
			ret = exfat_get_next_cluster(sb, &clu.dir);
		}

		if (ret || clu.dir == EXFAT_EOF_CLUSTER) {
			/* just initialized hint_stat */
			hint_stat->clu = p_dir->dir;
			hint_stat->eidx = 0;
			return (dentry - num_ext);
		}
	}

	hint_stat->clu = clu.dir;
	hint_stat->eidx = dentry + 1;
	return dentry - num_ext;
}

int exfat_count_ext_entries(struct super_block *sb, struct exfat_chain *p_dir,
		int entry, struct exfat_dentry *ep)
{
	int i, count = 0;
	unsigned int type;
	struct exfat_dentry *ext_ep;
	struct buffer_head *bh;

	for (i = 0, entry++; i < ep->dentry.file.num_ext; i++, entry++) {
		ext_ep = exfat_get_dentry(sb, p_dir, entry, &bh, NULL);
		if (!ext_ep)
			return -EIO;

		type = exfat_get_entry_type(ext_ep);
		brelse(bh);
		if (type == TYPE_EXTEND || type == TYPE_STREAM)
			count++;
		else
			break;
	}
	return count;
}

int exfat_count_dir_entries(struct super_block *sb, struct exfat_chain *p_dir)
{
	int i, count = 0;
	int dentries_per_clu;
	unsigned int entry_type;
	struct exfat_chain clu;
	struct exfat_dentry *ep;
	struct exfat_sb_info *sbi = EXFAT_SB(sb);
	struct buffer_head *bh;

	dentries_per_clu = sbi->dentries_per_clu;

	exfat_chain_dup(&clu, p_dir);

	while (clu.dir != EXFAT_EOF_CLUSTER) {
		for (i = 0; i < dentries_per_clu; i++) {
			ep = exfat_get_dentry(sb, &clu, i, &bh, NULL);
			if (!ep)
				return -EIO;
			entry_type = exfat_get_entry_type(ep);
			brelse(bh);

			if (entry_type == TYPE_UNUSED)
				return count;
			if (entry_type != TYPE_DIR)
				continue;
			count++;
		}

		if (clu.flags == ALLOC_NO_FAT_CHAIN) {
			if (--clu.size > 0)
				clu.dir++;
			else
				clu.dir = EXFAT_EOF_CLUSTER;
		} else {
			if (exfat_get_next_cluster(sb, &(clu.dir)))
				return -EIO;
		}
	}

	return count;
}
