// SPDX-License-Identifier: GPL-2.0+
/*
 * fat_write.c
 *
 * R/W (V)FAT 12/16/32 filesystem implementation by Donggeun Kim
 */

#define LOG_CATEGORY LOGC_FS

#include <common.h>
#include <command.h>
#include <config.h>
#include <div64.h>
#include <fat.h>
#include <log.h>
#include <malloc.h>
#include <part.h>
#include <rand.h>
#include <asm/byteorder.h>
#include <asm/cache.h>
#include <linux/ctype.h>
#include <linux/math64.h>
#include "fat.c"

static dir_entry *find_directory_entry(fat_itr *itr, char *filename);
static int new_dir_table(fat_itr *itr);

/* Characters that may only be used in long file names */
static const char LONG_ONLY_CHARS[] = "+,;=[]";

/* Combined size of the name and ext fields in the directory entry */
#define SHORT_NAME_SIZE 11

/**
 * str2fat() - convert string to valid FAT name characters
 *
 * Stop when reaching end of @src or a period.
 * Ignore spaces.
 * Replace characters that may only be used in long names by underscores.
 * Convert lower case characters to upper case.
 *
 * To avoid assumptions about the code page we do not use characters
 * above 0x7f for the short name.
 *
 * @dest:	destination buffer
 * @src:	source buffer
 * @length:	size of destination buffer
 * Return:	number of bytes in destination buffer
 */
static int str2fat(char *dest, char *src, int length)
{
	int i;

	for (i = 0; i < length; ++src) {
		char c = *src;

		if (!c || c == '.')
			break;
		if (c == ' ')
			continue;
		if (strchr(LONG_ONLY_CHARS, c) || c > 0x7f)
			c = '_';
		else if (c >= 'a' && c <= 'z')
			c &= 0xdf;
		dest[i] = c;
		++i;
	}
	return i;
}

/**
 * fat_move_to_cluster() - position to first directory entry in cluster
 *
 * @itr:	directory iterator
 * @cluster	cluster
 * Return:	0 for success, -EIO on error
 */
static int fat_move_to_cluster(fat_itr *itr, unsigned int cluster)
{
	unsigned int nbytes;

	/* position to the start of the directory */
	itr->next_clust = cluster;
	itr->last_cluster = 0;
	if (!fat_next_cluster(itr, &nbytes))
		return -EIO;
	itr->dent = (dir_entry *)itr->block;
	itr->remaining = nbytes / sizeof(dir_entry) - 1;
	return 0;
}

/**
 * set_name() - set short name in directory entry
 *
 * The function determines if the @filename is a valid short name.
 * In this case no long name is needed.
 *
 * If a long name is needed, a short name is constructed.
 *
 * @itr:	directory iterator
 * @filename:	long file name
 * @shortname:	buffer of 11 bytes to receive chosen short name and extension
 * Return:	number of directory entries needed, negative on error
 */
static int set_name(fat_itr *itr, const char *filename, char *shortname)
{
	char *period;
	char *pos;
	int period_location;
	char buf[13];
	int i;
	int ret;
	struct nameext dirent;

	if (!filename)
		return -EIO;

	/* Initialize buffer */
	memset(&dirent, ' ', sizeof(dirent));

	/* Convert filename to upper case short name */
	period = strrchr(filename, '.');
	pos = (char *)filename;
	if (*pos == '.') {
		pos = period + 1;
		period = 0;
	}
	if (period)
		str2fat(dirent.ext, period + 1, sizeof(dirent.ext));
	period_location = str2fat(dirent.name, pos, sizeof(dirent.name));
	if (period_location < 0)
		return period_location;
	if (*dirent.name == ' ')
		*dirent.name = '_';
	/* 0xe5 signals a deleted directory entry. Replace it by 0x05. */
	if (*dirent.name == 0xe5)
		*dirent.name = 0x05;

	/* If filename and short name are the same, quit. */
	sprintf(buf, "%.*s.%.3s", period_location, dirent.name, dirent.ext);
	if (!strcmp(buf, filename)) {
		ret = 1;
		goto out;
	}

	/* Construct an indexed short name */
	for (i = 1; i < 0x200000; ++i) {
		int suffix_len;
		int suffix_start;
		int j;

		/* To speed up the search use random numbers */
		if (i < 10) {
			j = i;
		} else {
			j = 30 - fls(i);
			j = 10 + (rand() >> j);
		}
		sprintf(buf, "~%d", j);
		suffix_len = strlen(buf);
		suffix_start = 8 - suffix_len;
		if (suffix_start > period_location)
			suffix_start = period_location;
		memcpy(dirent.name + suffix_start, buf, suffix_len);
		if (*dirent.ext != ' ')
			sprintf(buf, "%.*s.%.3s", suffix_start + suffix_len,
				dirent.name, dirent.ext);
		else
			sprintf(buf, "%.*s", suffix_start + suffix_len,
				dirent.name);
		debug("generated short name: %s\n", buf);

		/* Check that the short name does not exist yet. */
		ret = fat_move_to_cluster(itr, itr->start_clust);
		if (ret)
			return ret;
		if (find_directory_entry(itr, buf))
			continue;

		debug("chosen short name: %s\n", buf);
		/* Each long name directory entry takes 13 characters. */
		ret = (strlen(filename) + 25) / 13;
		goto out;
	}
	return -EIO;
out:
	memcpy(shortname, &dirent, SHORT_NAME_SIZE);
	return ret;
}

static int total_sector;
static int disk_write(__u32 block, __u32 nr_blocks, void *buf)
{
	ulong ret;

	if (!cur_dev)
		return -1;

	if (cur_part_info.start + block + nr_blocks >
		cur_part_info.start + total_sector) {
		printf("error: overflow occurs\n");
		return -1;
	}

	ret = blk_dwrite(cur_dev, cur_part_info.start + block, nr_blocks, buf);
	if (nr_blocks && ret == 0)
		return -1;

	return ret;
}

/*
 * Write fat buffer into block device
 */
static int flush_dirty_fat_buffer(fsdata *mydata)
{
	int getsize = FATBUFBLOCKS;
	__u32 fatlength = mydata->fatlength;
	__u8 *bufptr = mydata->fatbuf;
	__u32 startblock = mydata->fatbufnum * FATBUFBLOCKS;

	debug("debug: evicting %d, dirty: %d\n", mydata->fatbufnum,
	      (int)mydata->fat_dirty);

	if ((!mydata->fat_dirty) || (mydata->fatbufnum == -1))
		return 0;

	/* Cap length if fatlength is not a multiple of FATBUFBLOCKS */
	if (startblock + getsize > fatlength)
		getsize = fatlength - startblock;

	startblock += mydata->fat_sect;

	/* Write FAT buf */
	if (disk_write(startblock, getsize, bufptr) < 0) {
		debug("error: writing FAT blocks\n");
		return -1;
	}

	if (mydata->fats == 2) {
		/* Update corresponding second FAT blocks */
		startblock += mydata->fatlength;
		if (disk_write(startblock, getsize, bufptr) < 0) {
			debug("error: writing second FAT blocks\n");
			return -1;
		}
	}
	mydata->fat_dirty = 0;

	return 0;
}

/**
 * fat_find_empty_dentries() - find a sequence of available directory entries
 *
 * @itr:	directory iterator
 * @count:	number of directory entries to find
 * Return:	0 on success or negative error number
 */
static int fat_find_empty_dentries(fat_itr *itr, int count)
{
	unsigned int cluster;
	dir_entry *dent;
	int remaining;
	unsigned int n = 0;
	int ret;

	ret = fat_move_to_cluster(itr, itr->start_clust);
	if (ret)
		return ret;

	for (;;) {
		if (!itr->dent) {
			log_debug("Not enough directory entries available\n");
			return -ENOSPC;
		}
		switch (itr->dent->nameext.name[0]) {
		case 0x00:
		case DELETED_FLAG:
			if (!n) {
				/* Remember first deleted directory entry */
				cluster = itr->clust;
				dent = itr->dent;
				remaining = itr->remaining;
			}
			++n;
			if (n == count)
				goto out;
			break;
		default:
			n = 0;
			break;
		}

		next_dent(itr);
		if (!itr->dent &&
		    (!itr->is_root || itr->fsdata->fatsize == 32) &&
		    new_dir_table(itr))
			return -ENOSPC;
	}
out:
	/* Position back to first directory entry */
	if (itr->clust != cluster) {
		ret = fat_move_to_cluster(itr, cluster);
		if (ret)
			return ret;
	}
	itr->dent = dent;
	itr->remaining = remaining;
	return 0;
}

/*
 * Set the file name information from 'name' into 'slotptr',
 */
static int str2slot(dir_slot *slotptr, const char *name, int *idx)
{
	int j, end_idx = 0;

	for (j = 0; j <= 8; j += 2) {
		if (name[*idx] == 0x00) {
			slotptr->name0_4[j] = 0;
			slotptr->name0_4[j + 1] = 0;
			end_idx++;
			goto name0_4;
		}
		slotptr->name0_4[j] = name[*idx];
		(*idx)++;
		end_idx++;
	}
	for (j = 0; j <= 10; j += 2) {
		if (name[*idx] == 0x00) {
			slotptr->name5_10[j] = 0;
			slotptr->name5_10[j + 1] = 0;
			end_idx++;
			goto name5_10;
		}
		slotptr->name5_10[j] = name[*idx];
		(*idx)++;
		end_idx++;
	}
	for (j = 0; j <= 2; j += 2) {
		if (name[*idx] == 0x00) {
			slotptr->name11_12[j] = 0;
			slotptr->name11_12[j + 1] = 0;
			end_idx++;
			goto name11_12;
		}
		slotptr->name11_12[j] = name[*idx];
		(*idx)++;
		end_idx++;
	}

	if (name[*idx] == 0x00)
		return 1;

	return 0;
/* Not used characters are filled with 0xff 0xff */
name0_4:
	for (; end_idx < 5; end_idx++) {
		slotptr->name0_4[end_idx * 2] = 0xff;
		slotptr->name0_4[end_idx * 2 + 1] = 0xff;
	}
	end_idx = 5;
name5_10:
	end_idx -= 5;
	for (; end_idx < 6; end_idx++) {
		slotptr->name5_10[end_idx * 2] = 0xff;
		slotptr->name5_10[end_idx * 2 + 1] = 0xff;
	}
	end_idx = 11;
name11_12:
	end_idx -= 11;
	for (; end_idx < 2; end_idx++) {
		slotptr->name11_12[end_idx * 2] = 0xff;
		slotptr->name11_12[end_idx * 2 + 1] = 0xff;
	}

	return 1;
}

static int flush_dir(fat_itr *itr);

/**
 * fill_dir_slot() - fill directory entries for long name
 *
 * @itr:	directory iterator
 * @l_name:	long name
 * @shortname:	short name
 * Return:	0 for success, -errno otherwise
 */
static int
fill_dir_slot(fat_itr *itr, const char *l_name, const char *shortname)
{
	__u8 temp_dir_slot_buffer[MAX_LFN_SLOT * sizeof(dir_slot)];
	dir_slot *slotptr = (dir_slot *)temp_dir_slot_buffer;
	__u8 counter = 0, checksum;
	int idx = 0, ret;

	/* Get short file name checksum value */
	checksum = mkcksum((void *)shortname);

	do {
		memset(slotptr, 0x00, sizeof(dir_slot));
		ret = str2slot(slotptr, l_name, &idx);
		slotptr->id = ++counter;
		slotptr->attr = ATTR_VFAT;
		slotptr->alias_checksum = checksum;
		slotptr++;
	} while (ret == 0);

	slotptr--;
	slotptr->id |= LAST_LONG_ENTRY_MASK;

	while (counter >= 1) {
		memcpy(itr->dent, slotptr, sizeof(dir_slot));
		slotptr--;
		counter--;

		if (!itr->remaining) {
			/* Write directory table to device */
			ret = flush_dir(itr);
			if (ret)
				return ret;
		}

		next_dent(itr);
		if (!itr->dent)
			return -EIO;
	}

	return 0;
}

/*
 * Set the entry at index 'entry' in a FAT (12/16/32) table.
 */
static int set_fatent_value(fsdata *mydata, __u32 entry, __u32 entry_value)
{
	__u32 bufnum, offset, off16;
	__u16 val1, val2;

	switch (mydata->fatsize) {
	case 32:
		bufnum = entry / FAT32BUFSIZE;
		offset = entry - bufnum * FAT32BUFSIZE;
		break;
	case 16:
		bufnum = entry / FAT16BUFSIZE;
		offset = entry - bufnum * FAT16BUFSIZE;
		break;
	case 12:
		bufnum = entry / FAT12BUFSIZE;
		offset = entry - bufnum * FAT12BUFSIZE;
		break;
	default:
		/* Unsupported FAT size */
		return -1;
	}

	/* Read a new block of FAT entries into the cache. */
	if (bufnum != mydata->fatbufnum) {
		int getsize = FATBUFBLOCKS;
		__u8 *bufptr = mydata->fatbuf;
		__u32 fatlength = mydata->fatlength;
		__u32 startblock = bufnum * FATBUFBLOCKS;

		/* Cap length if fatlength is not a multiple of FATBUFBLOCKS */
		if (startblock + getsize > fatlength)
			getsize = fatlength - startblock;

		if (flush_dirty_fat_buffer(mydata) < 0)
			return -1;

		startblock += mydata->fat_sect;

		if (disk_read(startblock, getsize, bufptr) < 0) {
			debug("Error reading FAT blocks\n");
			return -1;
		}
		mydata->fatbufnum = bufnum;
	}

	/* Mark as dirty */
	mydata->fat_dirty = 1;

	/* Set the actual entry */
	switch (mydata->fatsize) {
	case 32:
		((__u32 *) mydata->fatbuf)[offset] = cpu_to_le32(entry_value);
		break;
	case 16:
		((__u16 *) mydata->fatbuf)[offset] = cpu_to_le16(entry_value);
		break;
	case 12:
		off16 = (offset * 3) / 4;

		switch (offset & 0x3) {
		case 0:
			val1 = cpu_to_le16(entry_value) & 0xfff;
			((__u16 *)mydata->fatbuf)[off16] &= ~0xfff;
			((__u16 *)mydata->fatbuf)[off16] |= val1;
			break;
		case 1:
			val1 = cpu_to_le16(entry_value) & 0xf;
			val2 = (cpu_to_le16(entry_value) >> 4) & 0xff;

			((__u16 *)mydata->fatbuf)[off16] &= ~0xf000;
			((__u16 *)mydata->fatbuf)[off16] |= (val1 << 12);

			((__u16 *)mydata->fatbuf)[off16 + 1] &= ~0xff;
			((__u16 *)mydata->fatbuf)[off16 + 1] |= val2;
			break;
		case 2:
			val1 = cpu_to_le16(entry_value) & 0xff;
			val2 = (cpu_to_le16(entry_value) >> 8) & 0xf;

			((__u16 *)mydata->fatbuf)[off16] &= ~0xff00;
			((__u16 *)mydata->fatbuf)[off16] |= (val1 << 8);

			((__u16 *)mydata->fatbuf)[off16 + 1] &= ~0xf;
			((__u16 *)mydata->fatbuf)[off16 + 1] |= val2;
			break;
		case 3:
			val1 = cpu_to_le16(entry_value) & 0xfff;
			((__u16 *)mydata->fatbuf)[off16] &= ~0xfff0;
			((__u16 *)mydata->fatbuf)[off16] |= (val1 << 4);
			break;
		default:
			break;
		}

		break;
	default:
		return -1;
	}

	return 0;
}

/*
 * Determine the next free cluster after 'entry' in a FAT (12/16/32) table
 * and link it to 'entry'. EOC marker is not set on returned entry.
 */
static __u32 determine_fatent(fsdata *mydata, __u32 entry)
{
	__u32 next_fat, next_entry = entry + 1;

	while (1) {
		next_fat = get_fatent(mydata, next_entry);
		if (next_fat == 0) {
			/* found free entry, link to entry */
			set_fatent_value(mydata, entry, next_entry);
			break;
		}
		next_entry++;
	}
	debug("FAT%d: entry: %08x, entry_value: %04x\n",
	       mydata->fatsize, entry, next_entry);

	return next_entry;
}

/**
 * set_sectors() - write data to sectors
 *
 * Write 'size' bytes from 'buffer' into the specified sector.
 *
 * @mydata:	data to be written
 * @startsect:	sector to be written to
 * @buffer:	data to be written
 * @size:	bytes to be written (but not more than the size of a cluster)
 * Return:	0 on success, -1 otherwise
 */
static int
set_sectors(fsdata *mydata, u32 startsect, u8 *buffer, u32 size)
{
	int ret;

	debug("startsect: %d\n", startsect);

	if ((unsigned long)buffer & (ARCH_DMA_MINALIGN - 1)) {
		ALLOC_CACHE_ALIGN_BUFFER(__u8, tmpbuf, mydata->sect_size);

		debug("FAT: Misaligned buffer address (%p)\n", buffer);

		while (size >= mydata->sect_size) {
			memcpy(tmpbuf, buffer, mydata->sect_size);
			ret = disk_write(startsect++, 1, tmpbuf);
			if (ret != 1) {
				debug("Error writing data (got %d)\n", ret);
				return -1;
			}

			buffer += mydata->sect_size;
			size -= mydata->sect_size;
		}
	} else if (size >= mydata->sect_size) {
		u32 nsects;

		nsects = size / mydata->sect_size;
		ret = disk_write(startsect, nsects, buffer);
		if (ret != nsects) {
			debug("Error writing data (got %d)\n", ret);
			return -1;
		}

		startsect += nsects;
		buffer += nsects * mydata->sect_size;
		size -= nsects * mydata->sect_size;
	}

	if (size) {
		ALLOC_CACHE_ALIGN_BUFFER(__u8, tmpbuf, mydata->sect_size);
		/* Do not leak content of stack */
		memset(tmpbuf, 0, mydata->sect_size);
		memcpy(tmpbuf, buffer, size);
		ret = disk_write(startsect, 1, tmpbuf);
		if (ret != 1) {
			debug("Error writing data (got %d)\n", ret);
			return -1;
		}
	}

	return 0;
}

/**
 * set_cluster() - write data to cluster
 *
 * Write 'size' bytes from 'buffer' into the specified cluster.
 *
 * @mydata:	data to be written
 * @clustnum:	cluster to be written to
 * @buffer:	data to be written
 * @size:	bytes to be written (but not more than the size of a cluster)
 * Return:	0 on success, -1 otherwise
 */
static int
set_cluster(fsdata *mydata, u32 clustnum, u8 *buffer, u32 size)
{
	return set_sectors(mydata, clust_to_sect(mydata, clustnum),
			   buffer, size);
}

/**
 * flush_dir() - flush directory
 *
 * @itr:	directory iterator
 * Return:	0 for success, -EIO on error
 */
static int flush_dir(fat_itr *itr)
{
	fsdata *mydata = itr->fsdata;
	u32 startsect, sect_offset, nsects;
	int ret;

	if (!itr->is_root || mydata->fatsize == 32) {
		ret = set_cluster(mydata, itr->clust, itr->block,
				  mydata->clust_size * mydata->sect_size);
		goto out;
	}

	sect_offset = itr->clust * mydata->clust_size;
	startsect = mydata->rootdir_sect + sect_offset;
	/* do not write past the end of rootdir */
	nsects = min_t(u32, mydata->clust_size,
		       mydata->rootdir_size - sect_offset);

	ret = set_sectors(mydata, startsect, itr->block,
			  nsects * mydata->sect_size);
out:
	if (ret) {
		log_err("Error: writing directory entry\n");
		return -EIO;
	}
	return 0;
}

/*
 * Read and modify data on existing and consecutive cluster blocks
 */
static int
get_set_cluster(fsdata *mydata, __u32 clustnum, loff_t pos, __u8 *buffer,
		loff_t size, loff_t *gotsize)
{
	static u8 *tmpbuf_cluster;
	unsigned int bytesperclust = mydata->clust_size * mydata->sect_size;
	__u32 startsect;
	loff_t wsize;
	int clustcount, i, ret;

	*gotsize = 0;
	if (!size)
		return 0;

	if (!tmpbuf_cluster) {
		tmpbuf_cluster = memalign(ARCH_DMA_MINALIGN, MAX_CLUSTSIZE);
		if (!tmpbuf_cluster)
			return -1;
	}

	assert(pos < bytesperclust);
	startsect = clust_to_sect(mydata, clustnum);

	debug("clustnum: %d, startsect: %d, pos: %lld\n",
	      clustnum, startsect, pos);

	/* partial write at beginning */
	if (pos) {
		wsize = min(bytesperclust - pos, size);
		ret = disk_read(startsect, mydata->clust_size, tmpbuf_cluster);
		if (ret != mydata->clust_size) {
			debug("Error reading data (got %d)\n", ret);
			return -1;
		}

		memcpy(tmpbuf_cluster + pos, buffer, wsize);
		ret = disk_write(startsect, mydata->clust_size, tmpbuf_cluster);
		if (ret != mydata->clust_size) {
			debug("Error writing data (got %d)\n", ret);
			return -1;
		}

		size -= wsize;
		buffer += wsize;
		*gotsize += wsize;

		startsect += mydata->clust_size;

		if (!size)
			return 0;
	}

	/* full-cluster write */
	if (size >= bytesperclust) {
		clustcount = lldiv(size, bytesperclust);

		if (!((unsigned long)buffer & (ARCH_DMA_MINALIGN - 1))) {
			wsize = clustcount * bytesperclust;
			ret = disk_write(startsect,
					 clustcount * mydata->clust_size,
					 buffer);
			if (ret != clustcount * mydata->clust_size) {
				debug("Error writing data (got %d)\n", ret);
				return -1;
			}

			size -= wsize;
			buffer += wsize;
			*gotsize += wsize;

			startsect += clustcount * mydata->clust_size;
		} else {
			for (i = 0; i < clustcount; i++) {
				memcpy(tmpbuf_cluster, buffer, bytesperclust);
				ret = disk_write(startsect,
						 mydata->clust_size,
						 tmpbuf_cluster);
				if (ret != mydata->clust_size) {
					debug("Error writing data (got %d)\n",
					      ret);
					return -1;
				}

				size -= bytesperclust;
				buffer += bytesperclust;
				*gotsize += bytesperclust;

				startsect += mydata->clust_size;
			}
		}
	}

	/* partial write at end */
	if (size) {
		wsize = size;
		ret = disk_read(startsect, mydata->clust_size, tmpbuf_cluster);
		if (ret != mydata->clust_size) {
			debug("Error reading data (got %d)\n", ret);
			return -1;
		}
		memcpy(tmpbuf_cluster, buffer, wsize);
		ret = disk_write(startsect, mydata->clust_size, tmpbuf_cluster);
		if (ret != mydata->clust_size) {
			debug("Error writing data (got %d)\n", ret);
			return -1;
		}

		size -= wsize;
		*gotsize += wsize;
	}

	assert(!size);

	return 0;
}

/*
 * Find the first empty cluster
 */
static int find_empty_cluster(fsdata *mydata)
{
	__u32 fat_val, entry = 3;

	while (1) {
		fat_val = get_fatent(mydata, entry);
		if (fat_val == 0)
			break;
		entry++;
	}

	return entry;
}

/**
 * new_dir_table() - allocate a cluster for additional directory entries
 *
 * @itr:	directory iterator
 * Return:	0 on success, -EIO otherwise
 */
static int new_dir_table(fat_itr *itr)
{
	fsdata *mydata = itr->fsdata;
	int dir_newclust = 0;
	int dir_oldclust = itr->clust;
	unsigned int bytesperclust = mydata->clust_size * mydata->sect_size;

	dir_newclust = find_empty_cluster(mydata);

	/*
	 * Flush before updating FAT to ensure valid directory structure
	 * in case of failure.
	 */
	itr->clust = dir_newclust;
	itr->next_clust = dir_newclust;
	memset(itr->block, 0x00, bytesperclust);
	if (flush_dir(itr))
		return -EIO;

	set_fatent_value(mydata, dir_oldclust, dir_newclust);
	if (mydata->fatsize == 32)
		set_fatent_value(mydata, dir_newclust, 0xffffff8);
	else if (mydata->fatsize == 16)
		set_fatent_value(mydata, dir_newclust, 0xfff8);
	else if (mydata->fatsize == 12)
		set_fatent_value(mydata, dir_newclust, 0xff8);

	if (flush_dirty_fat_buffer(mydata) < 0)
		return -EIO;

	itr->dent = (dir_entry *)itr->block;
	itr->last_cluster = 1;
	itr->remaining = bytesperclust / sizeof(dir_entry) - 1;

	return 0;
}

/*
 * Set empty cluster from 'entry' to the end of a file
 */
static int clear_fatent(fsdata *mydata, __u32 entry)
{
	__u32 fat_val;

	while (!CHECK_CLUST(entry, mydata->fatsize)) {
		fat_val = get_fatent(mydata, entry);
		if (fat_val != 0)
			set_fatent_value(mydata, entry, 0);
		else
			break;

		entry = fat_val;
	}

	/* Flush fat buffer */
	if (flush_dirty_fat_buffer(mydata) < 0)
		return -1;

	return 0;
}

/*
 * Set start cluster in directory entry
 */
static void set_start_cluster(const fsdata *mydata, dir_entry *dentptr,
			      __u32 start_cluster)
{
	if (mydata->fatsize == 32)
		dentptr->starthi =
			cpu_to_le16((start_cluster & 0xffff0000) >> 16);
	dentptr->start = cpu_to_le16(start_cluster & 0xffff);
}

/*
 * Check whether adding a file makes the file system to
 * exceed the size of the block device
 * Return -1 when overflow occurs, otherwise return 0
 */
static int check_overflow(fsdata *mydata, __u32 clustnum, loff_t size)
{
	__u32 startsect, sect_num, offset;

	if (clustnum > 0)
		startsect = clust_to_sect(mydata, clustnum);
	else
		startsect = mydata->rootdir_sect;

	sect_num = div_u64_rem(size, mydata->sect_size, &offset);

	if (offset != 0)
		sect_num++;

	if (startsect + sect_num > total_sector)
		return -1;
	return 0;
}

/*
 * Write at most 'maxsize' bytes from 'buffer' into
 * the file associated with 'dentptr'
 * Update the number of bytes written in *gotsize and return 0
 * or return -1 on fatal errors.
 */
static int
set_contents(fsdata *mydata, dir_entry *dentptr, loff_t pos, __u8 *buffer,
	     loff_t maxsize, loff_t *gotsize)
{
	unsigned int bytesperclust = mydata->clust_size * mydata->sect_size;
	__u32 curclust = START(dentptr);
	__u32 endclust = 0, newclust = 0;
	u64 cur_pos, filesize;
	loff_t offset, actsize, wsize;

	*gotsize = 0;
	filesize = pos + maxsize;

	debug("%llu bytes\n", filesize);

	if (!filesize) {
		if (!curclust)
			return 0;
		if (!CHECK_CLUST(curclust, mydata->fatsize) ||
		    IS_LAST_CLUST(curclust, mydata->fatsize)) {
			clear_fatent(mydata, curclust);
			set_start_cluster(mydata, dentptr, 0);
			return 0;
		}
		debug("curclust: 0x%x\n", curclust);
		debug("Invalid FAT entry\n");
		return -1;
	}

	if (!curclust) {
		assert(pos == 0);
		goto set_clusters;
	}

	/* go to cluster at pos */
	cur_pos = bytesperclust;
	while (1) {
		if (pos <= cur_pos)
			break;
		if (IS_LAST_CLUST(curclust, mydata->fatsize))
			break;

		newclust = get_fatent(mydata, curclust);
		if (!IS_LAST_CLUST(newclust, mydata->fatsize) &&
		    CHECK_CLUST(newclust, mydata->fatsize)) {
			debug("curclust: 0x%x\n", curclust);
			debug("Invalid FAT entry\n");
			return -1;
		}

		cur_pos += bytesperclust;
		curclust = newclust;
	}
	if (IS_LAST_CLUST(curclust, mydata->fatsize)) {
		assert(pos == cur_pos);
		goto set_clusters;
	}

	assert(pos < cur_pos);
	cur_pos -= bytesperclust;

	/* overwrite */
	assert(IS_LAST_CLUST(curclust, mydata->fatsize) ||
	       !CHECK_CLUST(curclust, mydata->fatsize));

	while (1) {
		/* search for allocated consecutive clusters */
		actsize = bytesperclust;
		endclust = curclust;
		while (1) {
			if (filesize <= (cur_pos + actsize))
				break;

			newclust = get_fatent(mydata, endclust);

			if (newclust != endclust + 1)
				break;
			if (IS_LAST_CLUST(newclust, mydata->fatsize))
				break;
			if (CHECK_CLUST(newclust, mydata->fatsize)) {
				debug("curclust: 0x%x\n", curclust);
				debug("Invalid FAT entry\n");
				return -1;
			}

			actsize += bytesperclust;
			endclust = newclust;
		}

		/* overwrite to <curclust..endclust> */
		if (pos < cur_pos)
			offset = 0;
		else
			offset = pos - cur_pos;
		wsize = min_t(unsigned long long, actsize, filesize - cur_pos);
		wsize -= offset;

		if (get_set_cluster(mydata, curclust, offset,
				    buffer, wsize, &actsize)) {
			printf("Error get-and-setting cluster\n");
			return -1;
		}
		buffer += wsize;
		*gotsize += wsize;
		cur_pos += offset + wsize;

		if (filesize <= cur_pos)
			break;

		if (IS_LAST_CLUST(newclust, mydata->fatsize))
			/* no more clusters */
			break;

		curclust = newclust;
	}

	if (filesize <= cur_pos) {
		/* no more write */
		newclust = get_fatent(mydata, endclust);
		if (!IS_LAST_CLUST(newclust, mydata->fatsize)) {
			/* truncate the rest */
			clear_fatent(mydata, newclust);

			/* Mark end of file in FAT */
			if (mydata->fatsize == 12)
				newclust = 0xfff;
			else if (mydata->fatsize == 16)
				newclust = 0xffff;
			else if (mydata->fatsize == 32)
				newclust = 0xfffffff;
			set_fatent_value(mydata, endclust, newclust);
		}

		return 0;
	}

	curclust = endclust;
	filesize -= cur_pos;
	assert(!do_div(cur_pos, bytesperclust));

set_clusters:
	/* allocate and write */
	assert(!pos);

	/* Assure that curclust is valid */
	if (!curclust) {
		curclust = find_empty_cluster(mydata);
		set_start_cluster(mydata, dentptr, curclust);
	} else {
		newclust = get_fatent(mydata, curclust);

		if (IS_LAST_CLUST(newclust, mydata->fatsize)) {
			newclust = determine_fatent(mydata, curclust);
			set_fatent_value(mydata, curclust, newclust);
			curclust = newclust;
		} else {
			debug("error: something wrong\n");
			return -1;
		}
	}

	/* TODO: already partially written */
	if (check_overflow(mydata, curclust, filesize)) {
		printf("Error: no space left: %llu\n", filesize);
		return -1;
	}

	actsize = bytesperclust;
	endclust = curclust;
	do {
		/* search for consecutive clusters */
		while (actsize < filesize) {
			newclust = determine_fatent(mydata, endclust);

			if ((newclust - 1) != endclust)
				/* write to <curclust..endclust> */
				goto getit;

			if (CHECK_CLUST(newclust, mydata->fatsize)) {
				debug("newclust: 0x%x\n", newclust);
				debug("Invalid FAT entry\n");
				return 0;
			}
			endclust = newclust;
			actsize += bytesperclust;
		}

		/* set remaining bytes */
		actsize = filesize;
		if (set_cluster(mydata, curclust, buffer, (u32)actsize) != 0) {
			debug("error: writing cluster\n");
			return -1;
		}
		*gotsize += actsize;

		/* Mark end of file in FAT */
		if (mydata->fatsize == 12)
			newclust = 0xfff;
		else if (mydata->fatsize == 16)
			newclust = 0xffff;
		else if (mydata->fatsize == 32)
			newclust = 0xfffffff;
		set_fatent_value(mydata, endclust, newclust);

		return 0;
getit:
		if (set_cluster(mydata, curclust, buffer, (u32)actsize) != 0) {
			debug("error: writing cluster\n");
			return -1;
		}
		*gotsize += actsize;
		filesize -= actsize;
		buffer += actsize;

		if (CHECK_CLUST(newclust, mydata->fatsize)) {
			debug("newclust: 0x%x\n", newclust);
			debug("Invalid FAT entry\n");
			return 0;
		}
		actsize = bytesperclust;
		curclust = endclust = newclust;
	} while (1);

	return 0;
}

/**
 * fill_dentry() - fill directory entry with shortname
 *
 * @mydata:		private filesystem parameters
 * @dentptr:		directory entry
 * @shortname:		chosen short name
 * @start_cluster:	first cluster of file
 * @size:		file size
 * @attr:		file attributes
 */
static void fill_dentry(fsdata *mydata, dir_entry *dentptr,
	const char *shortname, __u32 start_cluster, __u32 size, __u8 attr)
{
	memset(dentptr, 0, sizeof(*dentptr));

	set_start_cluster(mydata, dentptr, start_cluster);
	dentptr->size = cpu_to_le32(size);

	dentptr->attr = attr;

	memcpy(&dentptr->nameext, shortname, SHORT_NAME_SIZE);
}

/**
 * find_directory_entry() - find a directory entry by filename
 *
 * @itr:	directory iterator
 * @filename:	name of file to find
 * Return:	directory entry or NULL
 */
static dir_entry *find_directory_entry(fat_itr *itr, char *filename)
{
	int match = 0;

	while (fat_itr_next(itr)) {
		/* check both long and short name: */
		if (!strcasecmp(filename, itr->name))
			match = 1;
		else if (itr->name != itr->s_name &&
			 !strcasecmp(filename, itr->s_name))
			match = 1;

		if (!match)
			continue;

		if (itr->dent->nameext.name[0] == '\0')
			return NULL;
		else
			return itr->dent;
	}

	return NULL;
}

static int split_filename(char *filename, char **dirname, char **basename)
{
	char *p, *last_slash, *last_slash_cont;

again:
	p = filename;
	last_slash = NULL;
	last_slash_cont = NULL;
	while (*p) {
		if (ISDIRDELIM(*p)) {
			last_slash = p;
			last_slash_cont = p;
			/* continuous slashes */
			while (ISDIRDELIM(*p))
				last_slash_cont = p++;
			if (!*p)
				break;
		}
		p++;
	}

	if (last_slash) {
		if (last_slash_cont == (filename + strlen(filename) - 1)) {
			/* remove trailing slashes */
			*last_slash = '\0';
			goto again;
		}

		if (last_slash == filename) {
			/* avoid ""(null) directory */
			*dirname = "/";
		} else {
			*last_slash = '\0';
			*dirname = filename;
		}

		*last_slash_cont = '\0';
		filename = last_slash_cont + 1;
	} else {
		*dirname = "/"; /* root by default */
	}

	/*
	 * The FAT32 File System Specification v1.03 requires leading and
	 * trailing spaces as well as trailing periods to be ignored.
	 */
	for (; *filename == ' '; ++filename)
		;

	/* Keep special entries '.' and '..' */
	if (filename[0] == '.' &&
	    (!filename[1] || (filename[1] == '.' && !filename[2])))
		goto done;

	/* Remove trailing periods and spaces */
	for (p = filename + strlen(filename) - 1; p >= filename; --p) {
		switch (*p) {
		case ' ':
		case '.':
			*p = 0;
			break;
		default:
			goto done;
		}
	}

done:
	*basename = filename;

	return 0;
}

/**
 * normalize_longname() - check long file name and convert to lower case
 *
 * We assume here that the FAT file system is using an 8bit code page.
 * Linux typically uses CP437, EDK2 assumes CP1250.
 *
 * @l_filename:	preallocated buffer receiving the normalized name
 * @filename:	filename to normalize
 * Return:	0 on success, -1 on failure
 */
static int normalize_longname(char *l_filename, const char *filename)
{
	const char *p, illegal[] = "<>:\"/\\|?*";
	size_t len;

	len = strlen(filename);
	if (!len || len >= VFAT_MAXLEN_BYTES || filename[len - 1] == '.')
		return -1;

	for (p = filename; *p; ++p) {
		if ((unsigned char)*p < 0x20)
			return -1;
		if (strchr(illegal, *p))
			return -1;
	}

	strcpy(l_filename, filename);
	downcase(l_filename, VFAT_MAXLEN_BYTES);

	return 0;
}

int file_fat_write_at(const char *filename, loff_t pos, void *buffer,
		      loff_t size, loff_t *actwrite)
{
	dir_entry *retdent;
	fsdata datablock = { .fatbuf = NULL, };
	fsdata *mydata = &datablock;
	fat_itr *itr = NULL;
	int ret = -1;
	char *filename_copy, *parent, *basename;
	char l_filename[VFAT_MAXLEN_BYTES];

	debug("writing %s\n", filename);

	filename_copy = strdup(filename);
	if (!filename_copy)
		return -ENOMEM;

	split_filename(filename_copy, &parent, &basename);
	if (!strlen(basename)) {
		ret = -EINVAL;
		goto exit;
	}

	if (normalize_longname(l_filename, basename)) {
		printf("FAT: illegal filename (%s)\n", basename);
		ret = -EINVAL;
		goto exit;
	}

	itr = malloc_cache_aligned(sizeof(fat_itr));
	if (!itr) {
		ret = -ENOMEM;
		goto exit;
	}

	ret = fat_itr_root(itr, &datablock);
	if (ret)
		goto exit;

	total_sector = datablock.total_sect;

	ret = fat_itr_resolve(itr, parent, TYPE_DIR);
	if (ret) {
		printf("%s: doesn't exist (%d)\n", parent, ret);
		goto exit;
	}

	retdent = find_directory_entry(itr, l_filename);

	if (retdent) {
		if (fat_itr_isdir(itr)) {
			ret = -EISDIR;
			goto exit;
		}

		/* A file exists */
		if (pos == -1)
			/* Append to the end */
			pos = FAT2CPU32(retdent->size);
		if (pos > retdent->size) {
			/* No hole allowed */
			ret = -EINVAL;
			goto exit;
		}

		/* Update file size in a directory entry */
		retdent->size = cpu_to_le32(pos + size);
	} else {
		/* Create a new file */
		char shortname[SHORT_NAME_SIZE];
		int ndent;

		if (pos) {
			/* No hole allowed */
			ret = -EINVAL;
			goto exit;
		}

		/* Check if long name is needed */
		ndent = set_name(itr, basename, shortname);
		if (ndent < 0) {
			ret = ndent;
			goto exit;
		}
		ret = fat_find_empty_dentries(itr, ndent);
		if (ret)
			goto exit;
		if (ndent > 1) {
			/* Set long name entries */
			ret = fill_dir_slot(itr, basename, shortname);
			if (ret)
				goto exit;
		}

		/* Set short name entry */
		fill_dentry(itr->fsdata, itr->dent, shortname, 0, size,
			    ATTR_ARCH);

		retdent = itr->dent;
	}

	ret = set_contents(mydata, retdent, pos, buffer, size, actwrite);
	if (ret < 0) {
		printf("Error: writing contents\n");
		ret = -EIO;
		goto exit;
	}
	debug("attempt to write 0x%llx bytes\n", *actwrite);

	/* Flush fat buffer */
	ret = flush_dirty_fat_buffer(mydata);
	if (ret) {
		printf("Error: flush fat buffer\n");
		ret = -EIO;
		goto exit;
	}

	/* Write directory table to device */
	ret = flush_dir(itr);

exit:
	free(filename_copy);
	free(mydata->fatbuf);
	free(itr);
	return ret;
}

int file_fat_write(const char *filename, void *buffer, loff_t offset,
		   loff_t maxsize, loff_t *actwrite)
{
	return file_fat_write_at(filename, offset, buffer, maxsize, actwrite);
}

static int fat_dir_entries(fat_itr *itr)
{
	fat_itr *dirs;
	fsdata fsdata = { .fatbuf = NULL, }, *mydata = &fsdata;
						/* for FATBUFSIZE */
	int count;

	dirs = malloc_cache_aligned(sizeof(fat_itr));
	if (!dirs) {
		debug("Error: allocating memory\n");
		count = -ENOMEM;
		goto exit;
	}

	/* duplicate fsdata */
	fat_itr_child(dirs, itr);
	fsdata = *dirs->fsdata;

	/* allocate local fat buffer */
	fsdata.fatbuf = malloc_cache_aligned(FATBUFSIZE);
	if (!fsdata.fatbuf) {
		debug("Error: allocating memory\n");
		count = -ENOMEM;
		goto exit;
	}
	fsdata.fatbufnum = -1;
	dirs->fsdata = &fsdata;

	for (count = 0; fat_itr_next(dirs); count++)
		;

exit:
	free(fsdata.fatbuf);
	free(dirs);
	return count;
}

/**
 * delete_single_dentry() - delete a single directory entry
 *
 * @itr:	directory iterator
 * Return:	0 for success
 */
static int delete_single_dentry(fat_itr *itr)
{
	struct dir_entry *dent = itr->dent;

	memset(dent, 0, sizeof(*dent));
	dent->nameext.name[0] = DELETED_FLAG;

	if (!itr->remaining)
		return flush_dir(itr);
	return 0;
}

/**
 * delete_long_name() - delete long name directory entries
 *
 * @itr:	directory iterator
 * Return:	0 for success
 */
static int delete_long_name(fat_itr *itr)
{
	int seqn = itr->dent->nameext.name[0] & ~LAST_LONG_ENTRY_MASK;

	while (seqn--) {
		struct dir_entry *dent;
		int ret;

		ret = delete_single_dentry(itr);
		if (ret)
			return ret;
		dent = next_dent(itr);
		if (!dent)
			return -EIO;
	}
	return 0;
}

/**
 * delete_dentry_long() - remove directory entry
 *
 * @itr:	directory iterator
 * Return:	0 for success
 */
static int delete_dentry_long(fat_itr *itr)
{
	fsdata *mydata = itr->fsdata;
	dir_entry *dent = itr->dent;

	/* free cluster blocks */
	clear_fatent(mydata, START(dent));
	if (flush_dirty_fat_buffer(mydata) < 0) {
		printf("Error: flush fat buffer\n");
		return -EIO;
	}
	/* Position to first directory entry for long name */
	if (itr->clust != itr->dent_clust) {
		int ret;

		ret = fat_move_to_cluster(itr, itr->dent_clust);
		if (ret)
			return ret;
	}
	itr->dent = itr->dent_start;
	itr->remaining = itr->dent_rem;
	dent = itr->dent_start;
	/* Delete long name */
	if ((dent->attr & ATTR_VFAT) == ATTR_VFAT &&
	    (dent->nameext.name[0] & LAST_LONG_ENTRY_MASK)) {
		int ret;

		ret = delete_long_name(itr);
		if (ret)
			return ret;
	}
	/* Delete short name */
	delete_single_dentry(itr);
	return flush_dir(itr);
}

int fat_unlink(const char *filename)
{
	fsdata fsdata = { .fatbuf = NULL, };
	fat_itr *itr = NULL;
	int n_entries, ret;
	char *filename_copy, *dirname, *basename;

	filename_copy = strdup(filename);
	if (!filename_copy) {
		printf("Error: allocating memory\n");
		ret = -ENOMEM;
		goto exit;
	}
	split_filename(filename_copy, &dirname, &basename);

	if (!strcmp(dirname, "/") && !strcmp(basename, "")) {
		printf("Error: cannot remove root\n");
		ret = -EINVAL;
		goto exit;
	}

	itr = malloc_cache_aligned(sizeof(fat_itr));
	if (!itr) {
		printf("Error: allocating memory\n");
		ret = -ENOMEM;
		goto exit;
	}

	ret = fat_itr_root(itr, &fsdata);
	if (ret)
		goto exit;

	total_sector = fsdata.total_sect;

	ret = fat_itr_resolve(itr, dirname, TYPE_DIR);
	if (ret) {
		printf("%s: doesn't exist (%d)\n", dirname, ret);
		ret = -ENOENT;
		goto exit;
	}

	if (!find_directory_entry(itr, basename)) {
		printf("%s: doesn't exist\n", basename);
		ret = -ENOENT;
		goto exit;
	}

	if (fat_itr_isdir(itr)) {
		n_entries = fat_dir_entries(itr);
		if (n_entries < 0) {
			ret = n_entries;
			goto exit;
		}
		if (n_entries > 2) {
			printf("Error: directory is not empty: %d\n",
			       n_entries);
			ret = -EINVAL;
			goto exit;
		}
	}

	ret = delete_dentry_long(itr);

exit:
	free(fsdata.fatbuf);
	free(itr);
	free(filename_copy);

	return ret;
}

int fat_mkdir(const char *dirname)
{
	dir_entry *retdent;
	fsdata datablock = { .fatbuf = NULL, };
	fsdata *mydata = &datablock;
	fat_itr *itr = NULL;
	char *dirname_copy, *parent, *basename;
	char l_dirname[VFAT_MAXLEN_BYTES];
	int ret = -1;
	loff_t actwrite;
	unsigned int bytesperclust;
	dir_entry *dotdent = NULL;

	dirname_copy = strdup(dirname);
	if (!dirname_copy)
		goto exit;

	split_filename(dirname_copy, &parent, &basename);
	if (!strlen(basename)) {
		ret = -EINVAL;
		goto exit;
	}

	if (normalize_longname(l_dirname, basename)) {
		printf("FAT: illegal filename (%s)\n", basename);
		ret = -EINVAL;
		goto exit;
	}

	itr = malloc_cache_aligned(sizeof(fat_itr));
	if (!itr) {
		ret = -ENOMEM;
		goto exit;
	}

	ret = fat_itr_root(itr, &datablock);
	if (ret)
		goto exit;

	total_sector = datablock.total_sect;

	ret = fat_itr_resolve(itr, parent, TYPE_DIR);
	if (ret) {
		printf("%s: doesn't exist (%d)\n", parent, ret);
		goto exit;
	}

	retdent = find_directory_entry(itr, l_dirname);

	if (retdent) {
		printf("%s: already exists\n", l_dirname);
		ret = -EEXIST;
		goto exit;
	} else {
		char shortname[SHORT_NAME_SIZE];
		int ndent;

		if (itr->is_root) {
			/* root dir cannot have "." or ".." */
			if (!strcmp(l_dirname, ".") ||
			    !strcmp(l_dirname, "..")) {
				ret = -EINVAL;
				goto exit;
			}
		}

		/* Check if long name is needed */
		ndent = set_name(itr, basename, shortname);
		if (ndent < 0) {
			ret = ndent;
			goto exit;
		}
		ret = fat_find_empty_dentries(itr, ndent);
		if (ret)
			goto exit;
		if (ndent > 1) {
			/* Set long name entries */
			ret = fill_dir_slot(itr, basename, shortname);
			if (ret)
				goto exit;
		}

		/* Set attribute as archive for regular file */
		fill_dentry(itr->fsdata, itr->dent, shortname, 0, 0,
			    ATTR_DIR | ATTR_ARCH);

		retdent = itr->dent;
	}

	/* Default entries */
	bytesperclust = mydata->clust_size * mydata->sect_size;
	dotdent = malloc_cache_aligned(bytesperclust);
	if (!dotdent) {
		ret = -ENOMEM;
		goto exit;
	}
	memset(dotdent, 0, bytesperclust);

	memcpy(&dotdent[0].nameext, ".          ", 11);
	dotdent[0].attr = ATTR_DIR | ATTR_ARCH;

	memcpy(&dotdent[1].nameext, "..         ", 11);
	dotdent[1].attr = ATTR_DIR | ATTR_ARCH;

	if (itr->is_root)
		set_start_cluster(mydata, &dotdent[1], 0);
	else
		set_start_cluster(mydata, &dotdent[1], itr->start_clust);

	ret = set_contents(mydata, retdent, 0, (__u8 *)dotdent,
			   bytesperclust, &actwrite);
	if (ret < 0) {
		printf("Error: writing contents\n");
		goto exit;
	}
	/* Write twice for "." */
	set_start_cluster(mydata, &dotdent[0], START(retdent));
	ret = set_contents(mydata, retdent, 0, (__u8 *)dotdent,
			   bytesperclust, &actwrite);
	if (ret < 0) {
		printf("Error: writing contents\n");
		goto exit;
	}

	/* Flush fat buffer */
	ret = flush_dirty_fat_buffer(mydata);
	if (ret) {
		printf("Error: flush fat buffer\n");
		ret = -EIO;
		goto exit;
	}

	/* Write directory table to device */
	ret = flush_dir(itr);

exit:
	free(dirname_copy);
	free(mydata->fatbuf);
	free(itr);
	free(dotdent);
	return ret;
}
