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

#include <linux/slab.h>
#include <linux/compat.h>
#include <linux/bio.h>
#include <linux/buffer_head.h>
#include <linux/filelock.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 int exfat_get_uniname_from_ext_entry(struct super_block *sb,
		struct exfat_chain *p_dir, int entry, unsigned short *uniname)
{
	int i, err;
	struct exfat_entry_set_cache es;
	unsigned int uni_len = 0, len;

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

	/*
	 * 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 = ES_IDX_FIRST_FILENAME; 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_put_dentry_set(&es, false);
	return 0;
}

/* 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, num_ext, err;
	unsigned int type, clu_offset, max_dentries;
	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;

	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;
	max_dentries = (unsigned int)min_t(u64, MAX_EXFAT_DENTRIES,
				(u64)EXFAT_CLU_TO_DEN(sbi->num_clusters, sbi));

	clu_offset = EXFAT_DEN_TO_CLU(dentry, sbi);
	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);
			if (!ep)
				return -EIO;

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

			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);

			*uni_name.name = 0x0;
			err = exfat_get_uniname_from_ext_entry(sb, &clu, i,
				uni_name.name);
			if (err) {
				brelse(bh);
				continue;
			}
			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);
			if (!ep)
				return -EIO;
			dir_entry->entry = i;
			dir_entry->dir = clu;
			brelse(bh);

			ei->hint_bmap.off = EXFAT_DEN_TO_CLU(dentry, sbi);
			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;
		}
	}

out:
	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 *file, struct dir_context *ctx)
{
	struct inode *inode = file_inode(file);
	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(file, 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)de.dir.dir << 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 & EXFAT_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;
}

WRAP_DIR_ITER(exfat_iterate) // FIXME!
const struct file_operations exfat_dir_operations = {
	.llseek		= generic_file_llseek,
	.read		= generic_read_dir,
	.iterate_shared	= shared_exfat_iterate,
	.unlocked_ioctl = exfat_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl = exfat_compat_ioctl,
#endif
	.fsync		= exfat_file_fsync,
	.setlease	= generic_setlease,
};

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, IS_DIRSYNC(inode));
	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 ES_ENTRY_NUM(len);
}

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) & EXFAT_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;
	}

	if (ep->type == EXFAT_VENDOR_EXT)
		return TYPE_VENDOR_EXT;
	if (ep->type == EXFAT_VENDOR_ALLOC)
		return TYPE_VENDOR_ALLOC;

	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(EXFAT_ATTR_SUBDIR);
	} else if (type == TYPE_FILE) {
		ep->type = EXFAT_FILE;
		ep->dentry.file.attr = cpu_to_le16(EXFAT_ATTR_ARCHIVE);
	}
}

static void exfat_init_stream_entry(struct exfat_dentry *ep,
		unsigned int start_clu, unsigned long long size)
{
	memset(ep, 0, sizeof(*ep));
	exfat_set_entry_type(ep, TYPE_STREAM);
	if (size == 0)
		ep->dentry.stream.flags = ALLOC_FAT_CHAIN;
	else
		ep->dentry.stream.flags = ALLOC_NO_FAT_CHAIN;
	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;
		}
	}
}

void exfat_init_dir_entry(struct exfat_entry_set_cache *es,
		unsigned int type, unsigned int start_clu,
		unsigned long long size, struct timespec64 *ts)
{
	struct super_block *sb = es->sb;
	struct exfat_sb_info *sbi = EXFAT_SB(sb);
	struct exfat_dentry *ep;

	ep = exfat_get_dentry_cached(es, ES_IDX_FILE);
	memset(ep, 0, sizeof(*ep));
	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);

	ep = exfat_get_dentry_cached(es, ES_IDX_STREAM);
	exfat_init_stream_entry(ep, start_clu, size);
}

static void exfat_free_benign_secondary_clusters(struct inode *inode,
		struct exfat_dentry *ep)
{
	struct super_block *sb = inode->i_sb;
	struct exfat_chain dir;
	unsigned int start_clu =
		le32_to_cpu(ep->dentry.generic_secondary.start_clu);
	u64 size = le64_to_cpu(ep->dentry.generic_secondary.size);
	unsigned char flags = ep->dentry.generic_secondary.flags;

	if (!(flags & ALLOC_POSSIBLE) || !start_clu || !size)
		return;

	exfat_chain_set(&dir, start_clu,
			EXFAT_B_TO_CLU_ROUND_UP(size, EXFAT_SB(sb)),
			flags);
	exfat_free_cluster(inode, &dir);
}

void exfat_init_ext_entry(struct exfat_entry_set_cache *es, int num_entries,
		struct exfat_uni_name *p_uniname)
{
	int i;
	unsigned short *uniname = p_uniname->name;
	struct exfat_dentry *ep;

	ep = exfat_get_dentry_cached(es, ES_IDX_FILE);
	ep->dentry.file.num_ext = (unsigned char)(num_entries - 1);

	ep = exfat_get_dentry_cached(es, ES_IDX_STREAM);
	ep->dentry.stream.name_len = p_uniname->name_len;
	ep->dentry.stream.name_hash = cpu_to_le16(p_uniname->name_hash);

	for (i = ES_IDX_FIRST_FILENAME; i < num_entries; i++) {
		ep = exfat_get_dentry_cached(es, i);
		exfat_init_name_entry(ep, uniname);
		uniname += EXFAT_FILE_NAME_LEN;
	}

	exfat_update_dir_chksum(es);
}

void exfat_remove_entries(struct inode *inode, struct exfat_entry_set_cache *es,
		int order)
{
	int i;
	struct exfat_dentry *ep;

	for (i = order; i < es->num_entries; i++) {
		ep = exfat_get_dentry_cached(es, i);

		if (exfat_get_entry_type(ep) & TYPE_BENIGN_SEC)
			exfat_free_benign_secondary_clusters(inode, ep);

		exfat_set_entry_type(ep, TYPE_DELETED);
	}

	if (order < es->num_entries)
		es->modified = true;
}

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

	for (i = ES_IDX_FILE; 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, ES_IDX_FILE);
	ep->dentry.file.checksum = cpu_to_le16(chksum);
	es->modified = true;
}

int exfat_put_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);

	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;
}

static 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;

	if (!exfat_test_bitmap(sb, clu)) {
		exfat_err(sb, "failed to test cluster bit(%u)", clu);
		return -EIO;
	}

	/* 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)
{
	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;

	return (struct exfat_dentry *)((*bh)->b_data + off);
}

enum exfat_validate_dentry_mode {
	ES_MODE_GET_FILE_ENTRY,
	ES_MODE_GET_STRM_ENTRY,
	ES_MODE_GET_NAME_ENTRY,
	ES_MODE_GET_CRITICAL_SEC_ENTRY,
	ES_MODE_GET_BENIGN_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_GET_FILE_ENTRY:
		if (type != TYPE_STREAM)
			return false;
		*mode = ES_MODE_GET_STRM_ENTRY;
		break;
	case ES_MODE_GET_STRM_ENTRY:
		if (type != TYPE_EXTEND)
			return false;
		*mode = ES_MODE_GET_NAME_ENTRY;
		break;
	case ES_MODE_GET_NAME_ENTRY:
		if (type & TYPE_BENIGN_SEC)
			*mode = ES_MODE_GET_BENIGN_SEC_ENTRY;
		else if (type != TYPE_EXTEND)
			return false;
		break;
	case ES_MODE_GET_BENIGN_SEC_ENTRY:
		/* Assume unreconized benign secondary entry */
		if (!(type & TYPE_BENIGN_SEC))
			return false;
		break;
	default:
		return false;
	}

	return true;
}

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.
 *
 * 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
 *   num_entries: specifies how many dentries should be included.
 *                It will be set to es->num_entries if it is not 0.
 *                If num_entries is 0, es->num_entries will be obtained
 *                from the first dentry.
 * out:
 *   es: pointer of entry set on success.
 * return:
 *   0 on success
 *   -error code on failure
 */
static int __exfat_get_dentry_set(struct exfat_entry_set_cache *es,
		struct super_block *sb, struct exfat_chain *p_dir, int entry,
		unsigned int num_entries)
{
	int ret, i, num_bh;
	unsigned int off;
	sector_t sec;
	struct exfat_sb_info *sbi = EXFAT_SB(sb);
	struct buffer_head *bh;

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

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

	memset(es, 0, sizeof(*es));
	es->sb = sb;
	es->modified = false;
	es->start_off = off;
	es->bh = es->__bh;

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

	if (num_entries == ES_ALL_ENTRIES) {
		struct exfat_dentry *ep;

		ep = exfat_get_dentry_cached(es, ES_IDX_FILE);
		if (ep->type != EXFAT_FILE) {
			brelse(bh);
			return -EIO;
		}

		num_entries = ep->dentry.file.num_ext + 1;
	}

	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_NOFS);
		if (!es->bh) {
			brelse(bh);
			return -ENOMEM;
		}
		es->bh[0] = bh;
	}

	for (i = 1; i < num_bh; i++) {
		/* get the next sector */
		if (exfat_is_last_sector_in_cluster(sbi, sec)) {
			unsigned int clu = exfat_sector_to_cluster(sbi, sec);

			if (p_dir->flags == ALLOC_NO_FAT_CHAIN)
				clu++;
			else if (exfat_get_next_cluster(sb, &clu))
				goto put_es;
			sec = exfat_cluster_to_sector(sbi, clu);
		} else {
			sec++;
		}

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

	return 0;

put_es:
	exfat_put_dentry_set(es, false);
	return -EIO;
}

int exfat_get_dentry_set(struct exfat_entry_set_cache *es,
		struct super_block *sb, struct exfat_chain *p_dir,
		int entry, unsigned int num_entries)
{
	int ret, i;
	struct exfat_dentry *ep;
	enum exfat_validate_dentry_mode mode = ES_MODE_GET_FILE_ENTRY;

	ret = __exfat_get_dentry_set(es, sb, p_dir, entry, num_entries);
	if (ret < 0)
		return ret;

	/* validate cached dentries */
	for (i = ES_IDX_STREAM; i < es->num_entries; i++) {
		ep = exfat_get_dentry_cached(es, i);
		if (!exfat_validate_entry(exfat_get_entry_type(ep), &mode))
			goto put_es;
	}
	return 0;

put_es:
	exfat_put_dentry_set(es, false);
	return -EIO;
}

static int exfat_validate_empty_dentry_set(struct exfat_entry_set_cache *es)
{
	struct exfat_dentry *ep;
	struct buffer_head *bh;
	int i, off;
	bool unused_hit = false;

	/*
	 * ONLY UNUSED OR DELETED DENTRIES ARE ALLOWED:
	 * Although it violates the specification for a deleted entry to
	 * follow an unused entry, some exFAT implementations could work
	 * like this. Therefore, to improve compatibility, let's allow it.
	 */
	for (i = 0; i < es->num_entries; i++) {
		ep = exfat_get_dentry_cached(es, i);
		if (ep->type == EXFAT_UNUSED) {
			unused_hit = true;
		} else if (!IS_EXFAT_DELETED(ep->type)) {
			if (unused_hit)
				goto err_used_follow_unused;
			i++;
			goto count_skip_entries;
		}
	}

	return 0;

err_used_follow_unused:
	off = es->start_off + (i << DENTRY_SIZE_BITS);
	bh = es->bh[EXFAT_B_TO_BLK(off, es->sb)];

	exfat_fs_error(es->sb,
		"in sector %lld, dentry %d should be unused, but 0x%x",
		bh->b_blocknr, off >> DENTRY_SIZE_BITS, ep->type);

	return -EIO;

count_skip_entries:
	es->num_entries = EXFAT_B_TO_DEN(EXFAT_BLK_TO_B(es->num_bh, es->sb) - es->start_off);
	for (; i < es->num_entries; i++) {
		ep = exfat_get_dentry_cached(es, i);
		if (IS_EXFAT_DELETED(ep->type))
			break;
	}

	return i;
}

/*
 * Get an empty dentry set.
 *
 * in:
 *   sb+p_dir+entry: indicates the empty dentry location
 *   num_entries: specifies how many empty dentries should be included.
 * out:
 *   es: pointer of empty dentry set on success.
 * return:
 *   0  : on success
 *   >0 : the dentries are not empty, the return value is the number of
 *        dentries to be skipped for the next lookup.
 *   <0 : on failure
 */
int exfat_get_empty_dentry_set(struct exfat_entry_set_cache *es,
		struct super_block *sb, struct exfat_chain *p_dir,
		int entry, unsigned int num_entries)
{
	int ret;

	ret = __exfat_get_dentry_set(es, sb, p_dir, entry, num_entries);
	if (ret < 0)
		return ret;

	ret = exfat_validate_empty_dentry_set(es);
	if (ret)
		exfat_put_dentry_set(es, false);

	return ret;
}

static inline void exfat_reset_empty_hint(struct exfat_hint_femp *hint_femp)
{
	hint_femp->eidx = EXFAT_HINT_NONE;
	hint_femp->count = 0;
}

static inline void exfat_set_empty_hint(struct exfat_inode_info *ei,
		struct exfat_hint_femp *candi_empty, struct exfat_chain *clu,
		int dentry, int num_entries, int entry_type)
{
	if (ei->hint_femp.eidx == EXFAT_HINT_NONE ||
	    ei->hint_femp.eidx > dentry) {
		int total_entries = EXFAT_B_TO_DEN(i_size_read(&ei->vfs_inode));

		if (candi_empty->count == 0) {
			candi_empty->cur = *clu;
			candi_empty->eidx = dentry;
		}

		if (entry_type == TYPE_UNUSED)
			candi_empty->count += total_entries - dentry;
		else
			candi_empty->count++;

		if (candi_empty->count == num_entries ||
		    candi_empty->count + candi_empty->eidx == total_entries)
			ei->hint_femp = *candi_empty;
	}
}

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,
		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;
	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);
	int num_entries = exfat_calc_num_entries(p_uniname);
	unsigned int clu_count = 0;

	if (num_entries < 0)
		return num_entries;

	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;
	}

	exfat_reset_empty_hint(&ei->hint_femp);

rewind:
	order = 0;
	step = DIRENT_STEP_FILE;
	exfat_reset_empty_hint(&candi_empty);

	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);
			if (!ep)
				return -EIO;

			entry_type = exfat_get_entry_type(ep);

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

				exfat_set_empty_hint(ei, &candi_empty, &clu,
						dentry, num_entries,
						entry_type);

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

			exfat_reset_empty_hint(&candi_empty);

			if (entry_type == TYPE_FILE || entry_type == TYPE_DIR) {
				step = DIRENT_STEP_FILE;
				hint_opt->clu = clu.dir;
				hint_opt->eidx = i;
				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;

			/* break if the cluster chain includes a loop */
			if (unlikely(++clu_count > EXFAT_DATA_CLUSTER_COUNT(sbi)))
				goto not_found;
		}
	}

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;
		goto rewind;
	}

	/*
	 * set the EXFAT_EOF_CLUSTER flag to avoid search
	 * from the beginning again when allocated a new cluster
	 */
	if (ei->hint_femp.eidx == EXFAT_HINT_NONE) {
		ei->hint_femp.cur.dir = EXFAT_EOF_CLUSTER;
		ei->hint_femp.eidx = p_dir->size * dentries_per_clu;
		ei->hint_femp.count = 0;
	}

	/* 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_dir_entries(struct super_block *sb, struct exfat_chain *p_dir)
{
	int i, count = 0;
	int dentries_per_clu;
	unsigned int entry_type;
	unsigned int clu_count = 0;
	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);
			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;

			if (unlikely(++clu_count > sbi->used_clusters)) {
				exfat_fs_error(sb, "FAT or bitmap is corrupted");
				return -EIO;
			}

		}
	}

	return count;
}

static int exfat_get_volume_label_dentry(struct super_block *sb,
		struct exfat_entry_set_cache *es)
{
	int i;
	int dentry = 0;
	unsigned int type;
	struct exfat_sb_info *sbi = EXFAT_SB(sb);
	struct exfat_hint_femp hint_femp;
	struct exfat_inode_info *ei = EXFAT_I(sb->s_root->d_inode);
	struct exfat_chain clu;
	struct exfat_dentry *ep;
	struct buffer_head *bh;

	hint_femp.eidx = EXFAT_HINT_NONE;
	exfat_chain_set(&clu, sbi->root_dir, 0, ALLOC_FAT_CHAIN);

	while (clu.dir != EXFAT_EOF_CLUSTER) {
		for (i = 0; i < sbi->dentries_per_clu; i++, dentry++) {
			ep = exfat_get_dentry(sb, &clu, i, &bh);
			if (!ep)
				return -EIO;

			type = exfat_get_entry_type(ep);
			if (hint_femp.eidx == EXFAT_HINT_NONE) {
				if (type == TYPE_DELETED || type == TYPE_UNUSED) {
					hint_femp.cur = clu;
					hint_femp.eidx = dentry;
					hint_femp.count = 1;
				}
			}

			if (type == TYPE_UNUSED) {
				brelse(bh);
				goto not_found;
			}

			if (type != TYPE_VOLUME) {
				brelse(bh);
				continue;
			}

			memset(es, 0, sizeof(*es));
			es->sb = sb;
			es->bh = es->__bh;
			es->bh[0] = bh;
			es->num_bh = 1;
			es->start_off = EXFAT_DEN_TO_B(i) % sb->s_blocksize;

			return 0;
		}

		if (exfat_get_next_cluster(sb, &(clu.dir)))
			return -EIO;
	}

not_found:
	if (hint_femp.eidx == EXFAT_HINT_NONE) {
		hint_femp.cur.dir = EXFAT_EOF_CLUSTER;
		hint_femp.eidx = dentry;
		hint_femp.count = 0;
	}

	ei->hint_femp = hint_femp;

	return -ENOENT;
}

int exfat_read_volume_label(struct super_block *sb, struct exfat_uni_name *label_out)
{
	int ret, i;
	struct exfat_sb_info *sbi = EXFAT_SB(sb);
	struct exfat_entry_set_cache es;
	struct exfat_dentry *ep;

	mutex_lock(&sbi->s_lock);

	memset(label_out, 0, sizeof(*label_out));
	ret = exfat_get_volume_label_dentry(sb, &es);
	if (ret < 0) {
		/*
		 * ENOENT signifies that a volume label dentry doesn't exist
		 * We will treat this as an empty volume label and not fail.
		 */
		if (ret == -ENOENT)
			ret = 0;

		goto unlock;
	}

	ep = exfat_get_dentry_cached(&es, 0);
	label_out->name_len = ep->dentry.volume_label.char_count;
	if (label_out->name_len > EXFAT_VOLUME_LABEL_LEN) {
		ret = -EIO;
		exfat_put_dentry_set(&es, false);
		goto unlock;
	}

	for (i = 0; i < label_out->name_len; i++)
		label_out->name[i] = le16_to_cpu(ep->dentry.volume_label.volume_label[i]);

	exfat_put_dentry_set(&es, false);
unlock:
	mutex_unlock(&sbi->s_lock);
	return ret;
}

int exfat_write_volume_label(struct super_block *sb,
			     struct exfat_uni_name *label)
{
	int ret, i;
	struct exfat_sb_info *sbi = EXFAT_SB(sb);
	struct inode *root_inode = sb->s_root->d_inode;
	struct exfat_entry_set_cache es;
	struct exfat_chain clu;
	struct exfat_dentry *ep;

	if (label->name_len > EXFAT_VOLUME_LABEL_LEN)
		return -EINVAL;

	mutex_lock(&sbi->s_lock);

	ret = exfat_get_volume_label_dentry(sb, &es);
	if (ret == -ENOENT) {
		if (label->name_len == 0) {
			/* No volume label dentry, no need to clear */
			ret = 0;
			goto unlock;
		}

		ret = exfat_find_empty_entry(root_inode, &clu, 1, &es);
	}

	if (ret < 0)
		goto unlock;

	ep = exfat_get_dentry_cached(&es, 0);

	if (label->name_len == 0 && ep->dentry.volume_label.char_count == 0) {
		/* volume label had been cleared */
		exfat_put_dentry_set(&es, 0);
		goto unlock;
	}

	memset(ep, 0, sizeof(*ep));
	ep->type = EXFAT_VOLUME;

	for (i = 0; i < label->name_len; i++)
		ep->dentry.volume_label.volume_label[i] =
			cpu_to_le16(label->name[i]);

	ep->dentry.volume_label.char_count = label->name_len;
	es.modified = true;

	ret = exfat_put_dentry_set(&es, IS_DIRSYNC(root_inode));

unlock:
	mutex_unlock(&sbi->s_lock);
	return ret;
}
